【问题标题】:Convert XMLGregorianCalendar to java.time.Instant + switch timezone in the meanwhile将 XMLGregorianCalendar 转换为 java.time.Instant + 同时切换时区
【发布时间】:2018-09-23 18:27:22
【问题描述】:

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

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

【问题讨论】:

  • 完成并感谢您的推荐,注意!
  • 所以,它返回 CET,我需要 UTC,这很容易纠正,但我更担心的是,我认为使用时间可能会由于夏令时导致问题,还是我错了?
  • 是的,xgc 在 CST(美国/芝加哥)。我的意思是您推荐的.ofHours(-7) 解决方案返回了中欧时间的值。如果我将它设置为.ofHours(-5),它可以工作,但我们会遇到 DST 问题
  • 也很奇怪,现在我意识到 xgc.toGregorianCalendar().toZonedDateTime().getOffset() 返回 +2:00 ,我认为这是主要问题
  • 在您的帮助下,我弄清楚了它是如何工作的,所以非常感谢,我仍然需要考虑一下,为什么。如果我将代码更改为:.toGregorianCalendar().toZonedDateTime().withZoneSameLocal(ZoneId.of("America/Chicago")).toInstant(),它可以工作,我认为它应该随时正确

标签: java timezone


【解决方案1】:

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

    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)。

【讨论】:

    猜你喜欢
    • 2019-06-16
    • 1970-01-01
    • 2012-09-12
    • 2019-12-18
    • 1970-01-01
    • 2017-08-03
    • 2014-03-23
    • 1970-01-01
    • 2019-08-20
    相关资源
    最近更新 更多