Java 带有 DST 的时区打印不正确的时间(在负纪元中)

Java time zone with DST prints incorrect time (in negative epochs)

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

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

当 运行 在我的本地计算机上(Timezone GMT+2 Jerusalem) "Automatically adjust clock for DST" 签入 windows (这使我成为 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 时,它会打印出相同的结果。 我在这里错过了什么?

谢谢!

让我们看看您 1915 年的例子。值 -1712458800000 作为 millis-since-the-unix-epoch 是 1915-09-26T21:00:00Z - 换句话说,正好是晚上 9 点 UTC。

现在回到 1915 年,耶路撒冷的 UTC 偏移量是 +2:20:40,这就是您在输出的第一行看到 "Sep 26, 1915 11:20:40 PM" 的原因。但是,当您在 Windows 中关闭 DST 时,Windows 或 Java 将其视为 "Treat this as a fixed time zone of UTC+2." 并不是真正的 "Treat this as Jerusalem without DST changes, but with other changes." 所以您会看到一个值第二行中的 UTC+2,即 "Sun Sep 26 23:00:00 GMT+02:00 1915".

基本上,"this time zone without DST" 的概念是一个非常奇怪的概念,并且已被简化(同样,我不确定是 Windows 还是 Java)一个固定的偏移量。当 "standard" 偏移量没有改变时这很好,但是当它改变时会导致这样的问题。大多数时区在相当现代的历史中都没有改变它们的标准偏移量,但在 20 世纪初有相当多的变化。