简体   繁体   English

同时将XMLGregorianCalendar转换为java.time.Instant +切换时区

[英]Convert XMLGregorianCalendar to java.time.Instant + switch timezone in the meanwhile

I'm trying to convert a variable given in XMLGregorianCalendar to java.time.Instant. 我正在尝试将XMLGregorianCalendar中给定的变量转换为java.time.Instant。 Besides, the original variable is in Central Standard Time (America/Chicago) and I would need it in UTC. 此外,原始变量位于美国中部标准时间(美国/芝加哥),因此我需要UTC。 That's what I did, but it returns an Instant in UTC-7: 那就是我所做的,但是它在UTC-7中返回了Instant:

XMLGregorianCalendar xgc = header.getCaptureDate();
Instant convertedDateTime = xgc.toGregorianCalendar().toInstant().atOffset(ZoneOffset.UTC).toInstant();

I'm really confused what I'm doing wrong. 我真的很困惑我做错了什么。

The xgc looks like this: 2018-04-13T06:30:23 , and I would need this: 2018-04-13T11:30:23Z (Z added to the end, plus timezone changed). xgc看起来像这样: xgc 2018-04-13T06:30:23 ,而我需要这个: 2018-04-13T11:30:23Z (最后添加了Z,更改了时区)。 However, now I get this: 2018-04-13T04:30:23Z . 但是,现在我得到了: 2018-04-13T04:30:23Z

Thanks for the cooperation in finding a solution. 感谢您在寻找解决方案方面的合作。 I agree to your last comment: 我同意你的最后评论:

    Instant convertedDateTime = xgc.toGregorianCalendar()
            .toZonedDateTime()
            .withZoneSameLocal(ZoneId.of("America/Chicago"))
            .toInstant();
    System.out.println(convertedDateTime);

It prints the desired 它打印所需的

2018-04-13T11:30:23Z 2018-04-13T11:30:23Z

An Instant doesn't have a time zone. Instant没有时区。 It's toString method (called implicitly when we print it) produces a string in UTC. 它的toString方法(在打印时隐式调用)在UTC中生成一个字符串。 The Z at the end of the string means UTC or offset zero. 字符串末尾的Z表示UTC或偏移量为零。

Since we are giving a real time zone (America/Chicago), the code will adjust for summer time (daylight saving time) for us. 由于我们提供了一个实时时区(美国/芝加哥),因此该代码将为我们调整夏令时(夏令时)。 The only issue here is when in the fall the clock is turned backward. 唯一的问题是在秋天时钟何时倒转。 For example, November 4, 2018, the clock will be turned backward from 2 to 1, so if we get a time between 1 and 2, we cannot know whether it is in DST or not. 例如,2018年11月4日,时钟将从2倒转为1,因此如果我们获得介于1和2之间的时间,我们将无法知道它是否在DST中。 Had your XMLGregorianCalendar had a UTC offset in it, it would have given us an unambiguous point in time. 如果您的XMLGregorianCalendar中具有UTC偏移量,那么它将为我们提供明确的时间点。 But we had to supply that ourselves, which is what the withZoneSameLocal call did. 但是我们必须自己提供它,这是withZoneSameLocal调用所做的。

What went wrong in your code? 您的代码出了什么问题?

I suppose that your JVM's time zone setting is some Central European time zone (such as Europe/Oslo or Europe/Rome) which is on DST on April 13, that is, at UTC offset +02:00 (AKA CEST). 我想您的JVM的时区设置是某个中欧时区(例如Europe / Oslo或Europe / Rome),该时区于4月13日DST生效,即UTC偏移+02:00(AKA CEST)。 The XMLGregorianCalendar not having an offset in it, the conversion to Instant assumed that the time was in this time zone, so converted to 2018-04-13T04:30:23Z . XMLGregorianCalendar没有偏移量,到Instant的转换假定时间在该时区中,因此转换为2018-04-13T04:30:23Z Converting to OffsetDateTime and back to Instant made no difference. 转换为OffsetDateTime并返回Instant没什么区别。 You noted that it was 7 hours too early and assumed it was in time zone offset UTC-7 (which it wasn't; Z still means UTC). 您已经注意到,现在还早7个小时,并假设它所在的时区是UTC-7时区(不是; Z仍然表示UTC)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM