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.

Add Comment
1 Answer(s)

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:

  1. 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.
  2. 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.

Answered on July 16, 2020.
Add Comment

Your Answer

By posting your answer, you agree to the privacy policy and terms of service.