对于DST偏移量为负的特定历史日期,我得到了错误的时区名称。
时区数据库(tzdata)中的更新在1946-12-01至1947-02-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开始的Java8。
当在指定时间段内使用时间时,我得到错误的时区名称为"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
发布于 2019-06-23 23:06:30
至少在我看来,这个问题在OpenJDK历史上是这样的。
到目前为止,...OpenJDK通过使用tzdata的“后卫”版本来避免处理负DST,这个版本没有负DST (这个选项显然很快就会消失)。
我怀疑Oracle的Java到目前为止也一直在避免处理负的DST。
无论如何,我认为Java的时区实现不能很好地处理这些时区缩写。我尝试了下面这段示例代码:
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss zzz");
format.setTimeZone(TimeZone.getTimeZone(("Europe/Prague")));
for (int date = 1; date <= 28; ++date) {
System.out.println(format.format(new GregorianCalendar(1947, 1, date, 0, 0).getTime()));
}在假定的过渡日期之前和之后,...and名称保持为"CET“。
...
1947-02-20 05:00:00 CET
1947-02-21 05:00:00 CET
1947-02-22 05:00:00 CET
1947-02-23 06:00:00 CET
1947-02-24 06:00:00 CET
1947-02-25 06:00:00 CET
1947-02-26 06:00:00 CET
...如果我没记错的话,Java的时区实现根本没有保留这些缩写更改的历史记录,它只是对时区偏移量更改的转换时间进行编码。显示的缩写将根据当前标准呈现,而不是根据历史标准呈现。
编辑:我之前读错了tzdata,搞错了它的意思!
https://stackoverflow.com/questions/56724559
复制相似问题