较新 JDK 版本中的历史时区偏移

Bas*_*ers 18 java timezone-offset tzdata java-11

我在使用 . 测试一些时区时发现了一个奇怪的 java 差异ZonedDateTime。我试图解析 1970 年之前的日期,发现结果在 java 版本之间发生变化。1932 年荷兰的偏移量是+00:19。有谁知道为什么会发生这种情况?我觉得这可能与时区数据库项目( https://github.com/eggert/tz )中欧洲时区的捆绑有关,但我不确定。有没有办法获得java中的旧行为?就像设置一样?


ZonedDateTime zdt = LocalDateTime.parse("1932-10-20T10:19:32.000").atZone(ZoneId.of("Europe/Amsterdam"));
System.out.println(zdt);
    
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    .append(ISO_LOCAL_DATE)
    .appendLiteral('T')
    .appendValue(HOUR_OF_DAY, 2)
    .appendLiteral(':')
    .appendValue(MINUTE_OF_HOUR, 2)
    .optionalStart()
    .appendLiteral(':')
    .appendValue(SECOND_OF_MINUTE, 2)
    .optionalStart()
    .appendFraction(NANO_OF_SECOND, 3, 3, true)
    .appendOffset("+HH:MM", "Z")
    .toFormatter();

System.out.println(formatter.format(zdt));

System.out.println(
    java.time.zone.ZoneRulesProvider
                  .getVersions("UTC")
                  .lastEntry()
                  .getKey()
);
Run Code Online (Sandbox Code Playgroud)

结果 Temurin (java jdk) 11.0.16 (预期输出),最后一行显示时区数据库版本:

1932-10-20T10:19:32+00:19:32[Europe/Amsterdam]
1932-10-20T10:19:32.000+00:19
2022a
Run Code Online (Sandbox Code Playgroud)

Temurin 11.0.17 的结果:

1932-10-20T10:19:32Z[Europe/Amsterdam]
1932-10-20T10:19:32.000Z
2022c
Run Code Online (Sandbox Code Playgroud)

编辑:从 17.0.5 开始,JDK 17 中也存在一个问题:

铁木林 17.0.4:

1932-10-20T10:19:32+00:19:32[Europe/Amsterdam]
1932-10-20T10:19:32.000+00:19
2022a
Run Code Online (Sandbox Code Playgroud)

铁木林 17.0.5:

1932-10-20T10:19:32Z[Europe/Amsterdam]
1932-10-20T10:19:32.000Z
2022c
Run Code Online (Sandbox Code Playgroud)

Jer*_*oek 20

免责声明:我是OP的同事。这个问题让一半的办公室感到困惑。

在问题下方@Sweeper 的评论的帮助下,我认为我们已经找到了原因。

背景

久负盛名的时区数据库在 2022 年进行了一些清理工作,并将大量 1970 年之前的时区数据存档在其backzone版本2022b. 例如,这使得它们能够合并到Europe/BrusselsEurope/Amsterdam精简的 1970 年后数据库中(因为 1970 年之后,它们实际上是相等的)。

他们还引入了一个特殊选项 ( ),用于构建完整PACKRATLIST的历史时区的时区数据库。

OpenJDK 更新了时区数据库的新版本,但选择使用没有历史数据的版本,随后,一些开发人员注意到出现了问题

然而,相关的 OpenJDK 错误目前列出了支持backzoneas won't fix

受影响的 JDK

  • Java 11 从 11.0.17 开始。
  • Java 17 从 17.0.5 开始。

可能的解决方案

  • 也许较新的 JDK 会解决这个问题?此刻未知。
  • 或者,使用较新的 JDK,但应用此解决方法来安装旧版本 ( 2022a) 的时区数据库。
  • 或者,重写依赖于该历史数据的所有代码,如果是有限的集合,则可能通过硬编码相关时区偏移量来实现。

  • 谢谢。您可能想在答案本身中阐明 Coretto 的解决方法,因为这似乎是短期最安全且最不麻烦的解决方案,而且我不确定对 Corretto 问题的评论是否会在 Stack Overflow 的整个生命周期中保留。 (3认同)