I want to convert TimeZone such as \"America/Chicago\" to \"CST\". I can make use of SHORT_IDS map of ZoneID class. However, there are limited number of timezones configured in
Use TimeZone.getDisplayName:
TimeZone.getTimeZone("America/Chicago").getDisplayName(false, TimeZone.SHORT)
Ideone demo
But be very careful about using three-letter time zone identifiers. Only use them for display (as implied by the method name); do not use them to identify a time zone otherwise.
ZoneId hongKong = ZoneId.of("Asia/Hong_Kong");
System.out.println(hongKong.getDisplayName(TextStyle.SHORT_STANDALONE, Locale.ROOT));
This outputs:
HKT
Similarly the output for ZoneId.of("America/Chicago")
is CT
for Central Time (notice that this avoids the hopeless choice between CST for Central Standard Time and CDT for Central Daylight Time).
Please supply your desired locale. In many cases it won’t make any difference, in other cases it will since some time zones have localized abbreviations in some locales.
Unlike the outdated TimeZone
class the modern ZoneId
validates the time zone string and throws an exception if it is invalid, so we get a nice chance to correct any errors. For example:
java.time.DateTimeException: Invalid ID for region-based ZoneId, invalid format: Asia/Hong Kong
Edit: In this duplicate question it was asked to have the abbreviation for standard time (as opposed to summer time/DST). So CST, not CT, for America/Chicago, etc. It appeared that only US time zones needed to be supported. If so, this method does it:
private static final DateTimeFormatter ZONE_FORMATTER
= DateTimeFormatter.ofPattern("zzz", Locale.ENGLISH);
private static String getAbbreviationForStandardTime(ZoneId zone) {
ZonedDateTime timeInStandardTime = LocalDate.of(2021, Month.JANUARY, 1)
.atStartOfDay(zone);
if (zone.getRules().isDaylightSavings(timeInStandardTime.toInstant())) {
throw new IllegalArgumentException("Time zones that have summer time on January 1 are not supported");
}
return timeInStandardTime.format(ZONE_FORMATTER);
}
Let’s try it out:
System.out.println(getAbbreviationForStandardTime(ZoneId.of("America/Los_Angeles")));
System.out.println(getAbbreviationForStandardTime(ZoneId.of("America/Denver")));
System.out.println(getAbbreviationForStandardTime(ZoneId.of("America/Chicago")));
System.out.println(getAbbreviationForStandardTime(ZoneId.of("America/New_York")));
Output:
PST MST CST EST
My method includes a check that the time chosen — January 1 — is not in the summer time (DST) part of the year. For many time zones on the southern hemisphere this will fail. If you need to support any of them, the quick fix is to take July 1 instead in those cases.