带有DST的Java时区打印的时间不正确(在负时期内)

时间:2016-04-05 12:23:57

标签: java timezone timezone-offset

我很难理解以下代码的行为:

    TimeZone zone = TimeZone.getTimeZone("Asia/Jerusalem");
    DateFormat format = DateFormat.getDateTimeInstance();
    format.setTimeZone(zone);

    //printing out 4 different epoch dates

    //print out using formatter with TZ
    System.out.println(format.format(new Date(-1712458800000L))); 
    //print using Date's toString method
    System.out.println(new Date(-1712458800000L)); 

    System.out.println(format.format(new Date(-57844760000L)));
    System.out.println(new Date(-57844760000L));

    System.out.println(format.format(new Date(-1888228760000L)));
    System.out.println(new Date(-1888228760000L));

    System.out.println(format.format(new Date(1456920000000L)));
    System.out.println(new Date(1456920000000L));

在我的本地机器上运行时(时区GMT + 2耶路撒冷),在Windows中选中“自动调整DST时钟”(这使我GMT + 3) 它产生以下输出:

Sep 26, 1915 11:20:40 PM
Sun Sep 26 23:20:40 IST 1915

Mar 2, 1968 2:00:40 PM
Sat Mar 02 14:00:40 IST 1968

Mar 2, 1910 2:21:20 PM
Wed Mar 02 14:21:20 IST 1910

Mar 2, 2016 2:00:00 PM
Wed Mar 02 14:00:00 IST 2016

但是当我取消选中它(这使我GMT + 2)运行相同的代码时

Sep 26, 1915 11:20:40 PM
Sun Sep 26 23:00:00 GMT+02:00 1915

Mar 2, 1968 2:00:40 PM
Sat Mar 02 14:00:40 GMT+02:00 1968

Mar 2, 1910 2:21:20 PM
Wed Mar 02 14:00:40 GMT+02:00 1910

Mar 2, 2016 2:00:00 PM
Wed Mar 02 14:00:00 GMT+02:00 2016

第一个和第三个示例在使用Date的toString()时的分钟和秒数不同。 如您所见,当我使用DateFormat显式设置TZ时,它会输出相同的结果。 我在这里缺少什么?

谢谢!

1 个答案:

答案 0 :(得分:3)

让我们看看你1915年的例子。 -1712458800000作为毫升以来的unix-epoch是1915-09-26T21:00:00Z - 换句话说,正好是UTC时间晚上9点。

现在回到1915年,耶路撒冷的UTC偏移量为+2:20:40,这就是为什么你会看到" 1915年9月26日晚上11:20:40"在输出的第一行。但是,当您在Windows中关闭DST时,Windows或Java都会将其视为"将其视为UTC + 2的固定时区。"它不是真的"在没有DST变化的情况下将其视为耶路撒冷,但是还有其他变化。"所以你在第二行看到UTC + 2的值,即#34; Sun Sep 26 23:00:00 GMT + 02:00 1915"。

基本上,这个时区的概念没有DST"是一个非常奇怪的,并且已被简化(再次,我不确定它是由Windows还是Java)只是一个固定的偏移量。当"标准"时,这很好。偏移量不会发生变化,但会出现类似问题。大多数时区在合理的现代历史中都没有改变它们的标准偏差,但在20世纪初期又发生了不少变化。