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 世纪初有相当多的变化。
我很难理解以下代码的行为:
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 世纪初有相当多的变化。