I suppose you have read the comments stating how (almost) impossible and how fragile this is. I’m daring a few constructive suggestions anyway.
First you may of course handle GMT and UTC specially since the interpretations of these are fairly safe and you will probably want to make sure they are handled.
The next most safe thing to do, I think, is a bit complicated: Try ZoneId.of(yourNonIanaTimeZoneId)
. Either this gives you a ZoneId
or it throws an exception (in my experience typically a ZoneRulesException
, but according to the documentation it may also throw some other DateTimeException
). It gave me a ZoneId
for GMT, but neither for PLT
, IST
nor NET
. It does give a ZoneId
for EET
, for example. If you got a ZoneId
, you have not got far because its ID will just be the ID you gave. What you may do now is search through ZoneId.getAvailableZoneIds()
to see if you can find a zone with a IANA name and the same zone rules. You just need to know how to recognize a IANA name; I figure it should at least have a slash in it.
Next thing to try, look up in ZoneId.SHORT_IDS
. All of PLT
, IST
and NET
are there, for example. They are translated to Asia/Karachi, Asia/Kolkata and Asia/Yerevan. If you wanted, say, Irish Summer Time, you‘re badly off. Also, SHORT_IDS
will not always give you a IANA name but sometimes just an offset like -05:00
, which doesn’t really get you anywhere. For the three entries that do this, you may hardcode your own conversions, for example:
- EST = America/New_York
- HST = Pacific/Honolulu
- MST = America/Denver
Again, if for EST you wanted Eastern Standard Time in Australia (also known as AEST or AET), you’ve gone wrong. You will meet these ambiguities over and over.
You asked in a comment whether you can use TimeZone.getAvailableIDs()
. You can, but it doesn’t give you anything you don’t get from the above. I for my part would prefer to use the modern class ZoneId
over the outdated TimeZone
. In Java 8 they took out the short IDs (the use of which has been deprecated) into ZoneId.SHORT_IDS
and included all other IDs in ZoneId.getAvailableZoneIds()
. So every ID from TimeZone.getAvailableIDs()
is in either ZoneId.getAvailableZoneIds()
or ZoneId.SHORT_IDS
.
My last suggestion, I consider it dirty and it may not give you what you want:
SimpleDateFormat sdf = new SimpleDateFormat("z");
sdf.parse(yourNonIanaTimeZoneId);
String ianaName = sdf.getTimeZone().getID();
I am using the long outdated SimpleDateFormat
class, so I am not very happy about it. For PLT and NET it throws a ParseException
. For GMT it just gives me my JVM’s default time zone! For IST I got Asia/Jerusalem, so if you prefer this over Asia/Kolkata? However, some abbreviations that could not be handled by the previous methods are now converted, for example:
- EST to America/New_York
- EET (Eastern European Time) to Europe/Bucharest
- WET (Western European Time) to Africa/Casablanca
I make no guarantees about the quality of the conversions, especially the last one looks spooky in my eyes.
Use at your own risk! :-)