JodaTime与JDK OffsetDateTime的Pacific/Norfolk时区偏移差异及正确性验证
问题:JodaTime与JDK OffsetDateTime对Pacific/Norfolk时区偏移计算不一致
问题描述
测试发现JodaTime与JDK OffsetDateTime对Pacific/Norfolk时区的偏移计算结果不一致:JodaTime显示该时区2023年存在夏令时(DST)切换,1-3月、10-12月偏移为+12:00,4-9月为+11:00;而OffsetDateTime显示全年偏移均为+11:00。使用环境为Java 1.8.0.311、JodaTime 2.10.10,需确认哪一结果正确及是否存在代码错误。
测试代码
public static void main(String[] args) { System.out.println("Norfolk Island times as per Joda Time"); IntStream.range(1, 13) .forEach(month -> System.out.println(DateTime.now((DateTimeZone.forID("Pacific/Norfolk")) .withYear(2023) .withMonthOfYear(month) .withDayOfMonth(10) .withHourOfDay(2) .withMinuteOfHour(10) .withSecondOfMinute(2) .withMillisOfSecond(0)))); System.out.println("-------------------------------------"); System.out.println("Norfolk Island times as per JDK OffsetDateTime"); IntStream.range(1, 13) .forEach(month -> System.out.println(OffsetDateTime.now(ZoneId.of("Pacific/Norfolk")) .withYear(2023) .withMonth(month) .withDayOfMonth(10) .withHour(2) .withMinute(10) .withSecond(2) .withNano(0))); System.out.println("-------------------------------------"); }
输出结果
Norfolk Island times as per Joda Time 2023-01-10T02:10:02.000+12:00 2023-02-10T02:10:02.000+12:00 2023-03-10T02:10:02.000+12:00 2023-04-10T02:10:02.000+11:00 2023-05-10T02:10:02.000+11:00 2023-06-10T02:10:02.000+11:00 2023-07-10T02:10:02.000+11:00 2023-08-10T02:10:02.000+11:00 2023-09-10T02:10:02.000+11:00 2023-10-10T02:10:02.000+12:00 2023-11-10T02:10:02.000+12:00 2023-12-10T02:10:02.000+12:00 ------------------------------------- Norfolk Island times as per JDK OffsetDateTime 2023-01-10T02:10:02+11:00 2023-02-10T02:10:02+11:00 2023-03-10T02:10:02+11:00 2023-04-10T02:10:02+11:00 2023-05-10T02:10:02+11:00 2023-06-10T02:10:02+11:00 2023-07-10T02:10:02+11:00 2023-08-10T02:10:02+11:00 2023-09-10T02:10:02+11:00 2023-10-10T02:10:02+11:00 2023-11-10T02:10:02+11:00 2023-12-10T02:10:02+11:00 -------------------------------------
解答
- 结果正确性:JDK OffsetDateTime的结果是正确的。Norfolk Island自2016年起就取消了夏令时,全年固定使用
+11:00的时区偏移(NFT,诺福克岛时间)。 - 差异原因:两者依赖的时区数据库版本不一致。JodaTime 2.10.10的时区数据未更新到Norfolk Island取消夏令时的变更,仍保留旧的夏令时规则;而Java 8u311的时区数据已包含这一更新,因此计算结果准确。
- 代码问题:测试代码本身没有错误,无论是JodaTime还是JDK的时间构造方式都能正确生成目标时间点,差异完全来自底层时区数据的版本差异。
解决建议
- 若需继续使用JodaTime,可升级到包含最新时区数据的版本(如JodaTime 2.12.x及以上),或手动更新JodaTime的时区数据库文件。
- 优先使用JDK 8及以上自带的
java.timeAPI(如OffsetDateTime、ZonedDateTime),其时区数据可通过Java更新包(JRE的tzupdater工具或升级JDK版本)保持最新,避免第三方库的时区数据滞后问题。
内容的提问来源于stack exchange,提问作者Rajkishan Swami
相关产品推荐
相关产品推荐

