16

I found a weird java discrepancy while testing some timezones with the use of ZonedDateTime. I was trying to parse a date before 1970 and saw that the result changes between java versions. The offset for Netherlands in 1932 is +00:19. Does anyone know why this happens? I feel this might be related with the bundling of european timezones in the time zone database project (https://github.com/eggert/tz), but i'm not sure. Is there a way to get the old behavior in java? Like with a setting?


ZonedDateTime zdt = LocalDateTime.parse("1932-10-20T10:19:32.000").atZone(ZoneId.of("Europe/Amsterdam"));
System.out.println(zdt);
    
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    .append(ISO_LOCAL_DATE)
    .appendLiteral('T')
    .appendValue(HOUR_OF_DAY, 2)
    .appendLiteral(':')
    .appendValue(MINUTE_OF_HOUR, 2)
    .optionalStart()
    .appendLiteral(':')
    .appendValue(SECOND_OF_MINUTE, 2)
    .optionalStart()
    .appendFraction(NANO_OF_SECOND, 3, 3, true)
    .appendOffset("+HH:MM", "Z")
    .toFormatter();

System.out.println(formatter.format(zdt));

System.out.println(
    java.time.zone.ZoneRulesProvider
                  .getVersions("UTC")
                  .lastEntry()
                  .getKey()
);

Result in Temurin (java jdk) 11.0.16 (expected output), last line showing timezone database version:

1932-10-20T10:19:32+00:19:32[Europe/Amsterdam]
1932-10-20T10:19:32.000+00:19
2022a

Result in Temurin 11.0.17:

1932-10-20T10:19:32Z[Europe/Amsterdam]
1932-10-20T10:19:32.000Z
2022c

Edit: Also an issue in JDK 17 starting from 17.0.5:

Temurin 17.0.4:

1932-10-20T10:19:32+00:19:32[Europe/Amsterdam]
1932-10-20T10:19:32.000+00:19
2022a

Temurin 17.0.5:

1932-10-20T10:19:32Z[Europe/Amsterdam]
1932-10-20T10:19:32.000Z
2022c
  • On OpenJDK 17, I get the expected output. – Sweeper Feb 06 '23 at 09:56
  • @Sweeper Which exact version? This might very well have to do with timezone DB changes, which can vary by point release (e.g. I have the "wrong" output with Temurin 17.0.6.10). – Mark Rotteveel Feb 06 '23 at 10:00
  • 1
    Timezone database versions per JDK version: https://www.oracle.com/java/technologies/tzdata-versions.html – JeroenHoek Feb 06 '23 at 10:03
  • @OleV.V. The thing here though is that a *newer* version of the JDK, and the timezone database are giving different behaviour. – JeroenHoek Feb 06 '23 at 10:57
  • 1
    I checked a few versions of the tzdb and found that the amsterdam zone got moved from the europe file to the backzone file. Other than that, I couldn't find any significant changes on the versions I checked (all 2020a+). It might be helpful if you can [specify what version of tzdb you are using.](https://stackoverflow.com/a/41775223/5133585) – Sweeper Feb 06 '23 at 11:13
  • @Sweeper, I've edited the question with extra information regarding timezone database versions. – Bastiaan Sanders Feb 06 '23 at 11:49
  • 2
    Okay, I found it. It is [this line in this commit](https://github.com/eggert/tz/commit/0b925f6d8aaf927ac20049ae0ff3b527684b60c7#diff-b11f203e8e6ce90d0ab5a01a37ac248669987afb2a50fe0224fa8b8c5c985a73R964). They basically made Amsterdam an alias of Brussels because they share the same times post-1970. 2022b was the first version this change was applied to, it seems. – Sweeper Feb 06 '23 at 12:03
  • @Sweeper We (I'm a colleague of Bastiaan) suspected that that change might be relevant, but I figured that the move of that data to `backzone` was just administrative; not that it would actually change behaviour downstream! It seems like rather an impactful thing if it is. – JeroenHoek Feb 06 '23 at 12:08
  • 1
    I've found a related issue thread for the Corretto JDK here: https://github.com/corretto/corretto-17/issues/100 – JeroenHoek Feb 06 '23 at 12:17

1 Answers1

17

Disclaimer: I'm a colleague of OP. This issue has half the office baffled.

Helped along by comments by @Sweeper below the question, I think we've found the cause.

Background

The venerable Timezone Database did some housecleaning in 2022, and archived a lot of pre-1970 timezone data in their backzone file for version 2022b. This allowed them to merge, for example, Europe/Brussels and Europe/Amsterdam in the leaner post-1970 database (because after 1970, these are in fact equal).

They also introduced a special option (PACKRATLIST) for building the timezone database with the historic timezones intact.

OpenJDK updated to the new version of the Timezone Database, but chose to use the version without historical data, and subsequently, some developers noticed things breaking.

The relevant OpenJDK bug however currently lists supporting the backzone as won't fix.

Affected JDK's

  • Java 11 from 11.0.17 onwards.
  • Java 17 from 17.0.5 onwards.

Possible solutions

  • Perhaps newer JDK's will fix this after all? Unknown at this moment.
  • Alternatively, use the newer JDK's, but apply this workaround to install an older version (2022a) of the Timezone Database instead.
  • Or, rewrite all code that depends on this historical data, possibly by hardcoding the relevant timezone offsets if it is a limited set.
JeroenHoek
  • 1,448
  • 15
  • 24
  • 3
    Thanks. You may want to spell out the workaround from Coretto in the answer itself since this seems to be short-term safest and least hacky solution and since I am not sure whether the comment on the Corretto issue will stay for the lifetime of Stack Overflow. – Ole V.V. Feb 06 '23 at 14:50