Java – Why does negative DST time have a standard time zone name?

Why does negative DST time have a standard time zone name?… here is a solution to the problem.

Why does negative DST time have a standard time zone name?

I get the wrong time zone name for a specific historical date with a negative DST offset.


update to the time zone database (tzdata) introduced negative DST for the Europe/Prague region between 1946-12-01 and 1947-02-23.

This is the source of tzdata for Europe/Prague:

# 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

This new database has been in Java 8 since u181.

When using the time for a specified time period, I get the wrong time zone name like “CET”/”CET” instead of GMT as stated in tzdata.

Long timeInMilis = Long.parseLong("-725328000000");
String pattern = "yyyy-MM-dd HH:mm:ss zzz";
System.out.println(new SimpleDateFormat(pattern).format(new Date(timeInMilis)));
System.out.println(new SimpleDateFormat(pattern).format(new Date(timeInMilis)));

The result is

1947-01-07 01:00:00 CET
1947-01-07 00:00:00 CET

The first row is the Berlin time zone and the second row is the Prague time zone.
Both say it’s CET, but that’s wrong for Prague. It should say GMT as mentioned in the timezone database


At least as far as I know, in OpenJDK’s history of this issue….

… So far, OpenJDK has avoided dealing with negative DST by using tzdata’s “guard” version, which does not have negative DST (this option will obviously disappear soon).

I suspect Oracle’s Java has also avoided dealing with negative DST so far.

Anyway, I don’t think Java’s timezone implementation handles these timezone abbreviations well. I tried this sample code :

    SimpleDateFormat  format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss zzz");


for (int date = 1; date <= 28; ++date) {
      System.out.println(format.format(new GregorianCalendar(1947, 1, date, 0, 0).getTime()));

… and specify that “CET” be maintained before and after the assumed transition date.

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

If I’m not mistaken, Java’s timezone implementation doesn’t keep a history of these abbreviation changes at all, it just encodes the transition time for time zone shift changes. The abbreviations shown are presented according to current rather than historical standards.

EDIT: I misread tzdata earlier and got it wrong!

Related Problems and Solutions