【发布时间】:2019-06-23 13:54:43
【问题描述】:
对于具有负 DST 偏移的特定历史日期,我得到了错误的时区名称。
时区数据库 (tzdata) 的更新在 1946 年 12 月 1 日至 1947 年 2 月 23 日期间为欧洲/布拉格区引入了负 DST。
这是欧洲/布拉格的 tzdata 来源:
# We know of no English-language name for historical Czech winter time;
# abbreviate it as "GMT", as it happened to be GMT.
...
1:00 Czech CE%sT 1946 Dec 1 3:00
# Vanguard section, for zic and other parsers that support negative DST.
1:00 -1:00 GMT 1947 Feb 23 2:00
# Rearguard section, for parsers that do not support negative DST.
# 0:00 - GMT 1947 Feb 23 2:00
这个新数据库自 u181 以来就在 Java 8 中。
在指定时间段内使用时间时,我得到错误的时区名称为“CET”/“中欧时间”,而不是 tzdata 中所述的 GMT。
Long timeInMilis = Long.parseLong("-725328000000");
String pattern = "yyyy-MM-dd HH:mm:ss zzz";
TimeZone.setDefault(TimeZone.getTimeZone(("Europe/Berlin")));
System.out.println(new SimpleDateFormat(pattern).format(new Date(timeInMilis)));
TimeZone.setDefault(TimeZone.getTimeZone(("Europe/Prague")));
System.out.println(new SimpleDateFormat(pattern).format(new Date(timeInMilis)));
结果是
1947-01-07 01:00:00 CET
1947-01-07 00:00:00 CET
第一行是柏林时区,第二行是布拉格时区。 两者都说这是 CET,但对于布拉格来说这是错误的。它应该是时区数据库中提到的 GMT
【问题讨论】:
-
原因可能是区域名称不是直接取自 tzdata 中适用的行,而是取自 TimeZone 对象,它不知道日期是什么。如果您认为这种行为是错误的,您可能需要提交一个错误 - 尽管它可能只会针对
java.time类进行修复。 -
注意
Long.parseLong("-725328000000")应该写成-725328000000L。 -
或者更好的是
725_328_000_000L(也是@VGR) -
我建议你不要使用
TimeZone、SimpleDateFormat和Date。这些类设计不佳且早已过时,SimpleDateFormat特别是出了名的麻烦。而是使用Instant、ZoneId、ZonedDateTime和DateTimeFormatter,均来自java.time, the modern Java date and time API。