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

时间:2018-04-13 11:45:27

标签: java timezone

我试图将XMLGregorianCalendar中给出的变量转换为java.time.Instant。此外,原始变量是在中央标准时间(美国/芝加哥),我需要它在UTC。这就是我所做的,但它返回UTC-7中的瞬间:

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

我真的很困惑我做错了什么。

xgc看起来像这样:2018-04-13T06:30:23,我需要这样:2018-04-13T11:30:23Z(Z添加到最后,加上时区更改)。但是,现在我得到了这个:2018-04-13T04:30:23Z

1 个答案:

答案 0 :(得分:0)

感谢您在寻找解决方案方面的合作。我同意你的最后评论:

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

打印所需的

  

2018-04-13T11:30:23Z

Instant没有时区。它的toString方法(在我们打印时隐式调用)会生成一个UTC字符串。字符串末尾的Z表示UTC或偏移零。

由于我们提供了一个实时区域(美国/芝加哥),因此代码将针对我们调整夏令时(夏令时)。这里唯一的问题是秋天时钟倒转。例如,2018年11月4日,时钟将从2转为1,所以如果我们得到1到2之间的时间,我们无法知道它是否在DST中。如果你的XMLGregorianCalendar中有一个UTC偏移量,它会给我们一个明确的时间点。但我们必须自己提供,这是withZoneSameLocal调用所做的。

您的代码出了什么问题?

我认为您的JVM的时区设置是4月13日DST上的某个中欧时区(例如欧洲/奥斯陆或欧洲/罗马),即UTC偏移+02:00(AKA CEST) 。 XMLGregorianCalendar中没有偏移,转换为Instant假设时间在此时区,因此转换为2018-04-13T04:30:23Z。转换为OffsetDateTime并返回Instant没有任何区别。你注意到它太早了7个小时,并假设它在时区偏移UTC-7(它不是; Z仍然意味着UTC)。

相关问题