Is there a reason for java.time.ZoneId not including an Enum of ZoneIds?

Renan picture Renan · Jun 30, 2017 · Viewed 9.2k times · Source

To get a ZoneId it goes like:

ZoneId.of("America/Sao_Paulo");

or

ZoneId.of(ZoneId.SHORT_IDS.get("BET"));

Why would be the reason for not existing an Enum of such values, like:

ZoneId.of(ZoneIds.AMERICA_SAO_PAULO);

which seems less error-prone and a lot more auto-complete friendly?

Answer

user7605325 picture user7605325 · Jun 30, 2017

I believe it's because the list of all possible timezones names can change regardless of Java version.

Timezone information comes with Java installation (usually in the folder <java-home>/lib/zi, or in jre/lib/tzdb.dat file in newer versions). But this information can be updated without changing the Java version (using the Timezone Updater Tool).

If the timezone data is updated (but Java version stays the same) and a new zone ID is created, there would be no equivalent Enum for it, leaving the API "incomplete". And timezone data changes faster than JDK updates - even if it didn't, it's not always possible to update the JDK version in production environments as soon as we'd like.

I can't speak for the API creators, but I think they decided to leave it the way it is because the namespace can increase faster than the JDK is updated, and maintaining the enums up-to-date would be an endless and always-incomplete job.

If you really want to check if a timezone name is valid, you can do:

if (ZoneId.getAvailableZoneIds().contains("America/Sao_Paulo")) {
    // America/Sao_Paulo is a valid ID
}

Or just call ZoneId.of("zone-name") and catch the ZoneRulesException.


I've just called ZoneId.getAvailableZoneIds() in JDK 1.8.0_131 and it has 600 entries. Probably nobody wanted to create 600 enum constants.

One could argue that they could've done something similar to java.util.Locale class, which has a few entries for some languages (like English, German, French, etc). But how to decide which timezones "deserve" a constant? Maybe they just decided to not think too much about that and "hey, forget it, just use a String with the zone name".


Another possible reason can be the fact that ZoneId.of() method was designed to also receive UTC offsets (such as +05:00, -0300, +09:30:15 and so on). As the offsets accept hours, minutes and seconds, there are hundreds of possible offsets and creating enums for each one would be impractical.

Again, one could argue "Hey, create just the enums for the names and forget about the offsets". But the possible reasons for not creating enum names were already discussed above.