为什么DST时间为负数具有标准的区域名称?

时间:2019-06-23 13:54:43

标签: java timezone

我为DST偏移量为负的特定历史日期输入了错误的时区名称。

时区数据库(tzdata)中的更新在1946-12-01至1947-02-23期间为欧洲/布拉格带来了负面的夏令时。

这是欧洲/布拉格的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,但是对于布拉格来说,这是错误的。应该说时区数据库中提到的格林尼治标准时间

1 个答案:

答案 0 :(得分:3)

至少从我在本期有关OpenJDK的历史中可以看到的...

https://bugs.openjdk.java.net/browse/JDK-8195595?page=com.atlassian.jira.plugin.system.issuetabpanels%3Aall-tabpanel

...到目前为止,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()));
    }

...并且该名称在预期转换日期之前和之后保持为“ 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,并且误解了它的含义!