新版JDK中历史时区偏移不一致问题咨询
关于Temurin JDK版本中Europe/Amsterdam时区1932年偏移差异的问题
测试ZonedDateTime处理1970年前日期时发现,Europe/Amsterdam时区在1932年的偏移值在不同Temurin JDK版本中存在差异:
- 旧版Temurin 11.0.16、17.0.4中,偏移显示为
+00:19 - 新版Temurin 11.0.17、17.0.5中,偏移显示为
Z(UTC)
测试代码
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() );
各版本运行结果
Temurin 11.0.16 / 17.0.4(旧版输出)
1932-10-20T10:19:32+00:19:32[Europe/Amsterdam] 1932-10-20T10:19:32.000+00:19 2022a
Temurin 11.0.17 / 17.0.5(新版输出)
1932-10-20T10:19:32Z[Europe/Amsterdam] 1932-10-20T10:19:32.000Z 2022c
问题原因
差异的核心是JDK捆绑的时区数据库版本更新:
- 旧版JDK使用的是tzdb2022a,该版本保留了荷兰1932年之前使用的阿姆斯特丹平均时间(AMT,偏移+00:19:32)记录
- 新版JDK升级到了tzdb2022c,时区数据库项目在2022b/c版本中修正了欧洲历史时区数据,移除了早期的AMT记录,将1932年之前的Europe/Amsterdam时区统一映射为UTC,这是对历史时区标准的规范性修正
恢复旧版行为的方法
1. 手动加载旧版时区数据库
- 下载对应版本的tzdb文件(如tzdb2022a)
- 通过JVM参数或代码加载自定义时区规则:
- 使用JVM参数:
-Djava.time.zone.DefaultZoneRulesProvider=com.sun.time.calendar.ZoneRulesProviderImpl,并将旧版tzdb文件放置在指定路径 - 或者引入第三方时区库,替换默认的时区规则实现
- 使用JVM参数:
2. 代码层面适配(仅针对特定场景)
如果仅需处理1932年之前的荷兰时区,可以手动指定固定偏移:
// 针对1932年之前的日期,手动设置阿姆斯特丹平均时间偏移 ZoneOffset amtOffset = ZoneOffset.of("+00:19:32"); ZonedDateTime zdt = LocalDateTime.parse("1932-10-20T10:19:32.000").atOffset(amtOffset).atZoneSameInstant(ZoneId.of("Europe/Amsterdam"));
注意:此方法仅适用于特定历史日期范围,不建议全局替换时区规则。
内容的提问来源于stack exchange,提问作者Bastiaan Sanders
相关产品推荐
相关产品推荐

