Find standard time name for a region using Java
Is there anyway to find the standard time that comes under time zone regions, for example
America/New_York and America/NewJersey -> EST
I am developing a REST service where the request will have region-based timezone(America/NewJersey) as a parameter and I need to find the standard time it comes under and pass it to legacy API, which only accepts 3 digit timezone(EST/MST/CST/AET).
I am using Java 8 and I checked Time API, but it doesn’t have any such feature/functionality. As a workaround I can have a mapping in a file or DB, but just want to know if anybody else faced this and is there any clean solution to it.
If I understand correctly, the main requirement is to have some specific three letter abbreviations that an API outside of your control requires. So for example:
- EST for Eastern Standard Time (probably North American Eastern Standard Time?), not ET for Eastern Time.
- On the other hand AET for Australian Eastern Time, not AEST for Australian Eastern Standard Time (and also not EST for Eastern Standard Time even though I have read that EST is used as abbreviation in Australia too).
It seems to me that there is no systematic correspondence between the time zone abbreviations that Java knows (from CLDR or what locale data provider you are using) and the abbreviations required by that API. As a further problem three letter time zone abbreviations are often ambiguous, so I suspect that there are many time zones that your legacy API is simply unable to recognize (or for which it requires some obscure homespun abbreviation that we have little chance of guessing).
Approaches are two:
- The safe but also circumstantial and laborious way is the one that Deadpool has long suggested in a comment: Build and keep a mapping of the abbreviations required.
- See how far you can get with the abbreviations that Java knows. Be prepared that you won’t be able to cover all cases and that you may make an incorrect guess occasionally.
I will leave option 1. to yourself with my recommendation.
In case you want to try your luck with option 2., my attempt follows.
private static final DateTimeFormatter ZONE_FORMATTER = DateTimeFormatter.ofPattern("zzz", Locale.ENGLISH); private static String getThreeLetterAbbreviation(ZoneId zone) { // Try the display name first String displayName = zone.getDisplayName(TextStyle.SHORT_STANDALONE, Locale.ENGLISH); if (displayName.length() == 3) { return displayName; } // Try formatting a date in standard time; try southern hemisphere first ZonedDateTime timeInStandardTime = LocalDate.of(2021, Month.JULY, 1) .atStartOfDay(zone); if (zone.getRules().isDaylightSavings(timeInStandardTime.toInstant())) { // Then northern hemisphere timeInStandardTime = LocalDate.of(2021, Month.JANUARY, 1) .atStartOfDay(zone); if (zone.getRules().isDaylightSavings(timeInStandardTime.toInstant())) { throw new IllegalArgumentException("Unable to find a date in standard time"); } } return timeInStandardTime.format(ZONE_FORMATTER); }
This auxiliary method tries it out:
private static void printAbbreviation(String zid) { System.out.format("%19s -> %s%n", zid, getThreeLetterAbbreviation(ZoneId.of(zid))); }
So using it we go:
printAbbreviation("America/Los_Angeles"); printAbbreviation("America/Denver"); printAbbreviation("America/Chicago"); printAbbreviation("America/New_York"); printAbbreviation("Australia/Sydney");
Output:
America/Los_Angeles -> PST America/Denver -> MST America/Chicago -> CST America/New_York -> EST Australia/Sydney -> AET
I would not call it a clean solution. What I particularly fear about it is that the method will produce an incorrect result that your API interprets differently from the intended, and no one will notice that it in turn produces an incorrect result, or not until it’s too late. For example:
printAbbreviation("Asia/Shanghai");
Asia/Shanghai -> CST
Here CST is for China Standard Time, but my guess is that your API will understand it as North American Central Standard Time. We really should never rely on three letter time zone abbreviations. They are ambiguous, maybe more often than not. And as this question shows, they are not standardized.