问题
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?
回答1:
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.
回答2:
The set of time-zones in the JDK can be completely replaced.
As such, it is not possible to define an enum
for the zones.
In addition, the time-zone identifiers are relatively unstable. They get renamed, merged and generally changed. (Various people including me have tried to get more stability in the IANA database, but the database maintainer does not agree.)
A pull request to create a ZoneIds
class in ThreeTen-Extra providing constants would be considered.
回答3:
If you see the description of the ZoneId#getAvailableZoneIds method, then you know why?
This set includes the string form of all available region-based IDs. Offset-based zone IDs are not included in the returned set. The ID can be passed to
of(String)
to create a ZoneId.The set of zone IDs can increase over time, although in a typical application the set of IDs is fixed. Each call to this method is thread-safe.
来源:https://stackoverflow.com/questions/44836984/is-there-a-reason-for-java-time-zoneid-not-including-an-enum-of-zoneids