问题
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 that map. What if I want to get "Asia/Hong_Kong" to "HKT", then this map will not get me correct answer.
Is there any library which I can make use of, if something is not provided by Java. I am avoiding creating mapping of these timezones in my application.
Any advice here would be greatly appreciated.
回答1:
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.
回答2:
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
To get the abbreviation for standard time
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.
来源:https://stackoverflow.com/questions/52337305/converting-timezone-to-3-characters-zoneid