3

In late 2022, the timezone Europe/Kiev was renamed to Europe/Kyiv by IANA.

Consider the following program:

import java.time.ZoneId;

public class TZPlay {
  public static void main(String[] args) {
    try {
//      ZoneId.of("Europe/Kiev"); // Works in Java 17.06 and Java 17.03
//      ZoneId.of("Europe/Kyiv"); // Works in Java 17.06 but not Java 17.03.
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Observations:

  • Java 17.03 throws the following exception when trying to parse Europe/Kyiv.
java.time.zone.ZoneRulesException: Unknown time-zone ID: Europe/Kyiv
        at java.base/java.time.zone.ZoneRulesProvider.getProvider(ZoneRulesProvider.java:280)
        at java.base/java.time.zone.ZoneRulesProvider.getRules(ZoneRulesProvider.java:235)
        at java.base/java.time.ZoneRegion.ofId(ZoneRegion.java:121)
        at java.base/java.time.ZoneId.of(ZoneId.java:410)
        at java.base/java.time.ZoneId.of(ZoneId.java:358)
        at TZPlay.main(TZPlay.java:7)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:568)
        at jdk.compiler/com.sun.tools.javac.launcher.Main.execute(Main.java:419)
        at jdk.compiler/com.sun.tools.javac.launcher.Main.run(Main.java:192)
        at jdk.compiler/com.sun.tools.javac.launcher.Main.main(Main.java:132)
  • Java 17.06 correctly parses it without exception.
  • Moreover, Java 17.06 also parses Europe/Kiev without exception.

Empirically, based on the above example, it seems like newer versions of Java are able to parse older timezones after they were renamed.

Is this guaranteed to always be true, or will old timezones sometimes break on newer Java minor versions?

I searched the ZoneId javadoc for the terms "previous", "old" and "rename" but did not find anything obvious.

merlin2011
  • 71,677
  • 44
  • 195
  • 329

1 Answers1

2

It's not guaranteed. Java uses data from Common Locale Data Repository and they periodically update it.

There have been cases where that update was a breaking change, e.g. this: September's short form "Sep" no longer parses in Java 17 in en_GB locale

That zone just happens to have both of those examples as valid aliases. See: https://github.com/openjdk/jdk/blob/master/make/data/cldr/common/bcp47/timezone.xml#L398 but there is no requirement that they do so.

A zone name is not really something you should expect forwards compatibility for. This data models the real world, and the real world is constantly changing. If you want to rely on something that's future-proof, then use the offset, i.e. +02:00.

Michael
  • 41,989
  • 11
  • 82
  • 128
  • 1/2 Don't use the offset. Because different countries can have different DST date. So it can depend on when you need to use the timezone. For example, if you want to save the user's timezone to convert time to his timezone, you can't save just the offset, because it's different for each country for different dates. Example. Today is March of 2023 and you save your user timezone offset = +2 – Joao May 29 '23 at 16:27
  • 2/2 You save the offset +2 You receive two dates Wed Mar 20 2023 16:00:00 GMT+0200 Wed Mar 29 2023 16:00:00 GMT+0200 For Egyptian users, both dates you don't need to convert. Because Egypt implement DST in April For Ukrainian users, you need to convert one date Wed Mar 20 2023 16:00:00 GMT+0200 Wed Mar 29 2023 17:00:00 GMT+0300 because the 29th of Mar goes after DST. – Joao May 29 '23 at 16:27