2

I've timezones which are not in IANA format like PLT,IST,GMT,NET,etc. How to convert these to IANA format in java like Asia/Karachi,Asia/Kolkatta,Etc/Greenwich,etc.

I've tried with the offset values using TimeZone.getOffset() but it still needs IANA format.

Varshini
  • 187
  • 1
  • 6
  • 20
  • That's not working. It just abbreviates and shows but not in IANA format – Varshini Jul 25 '17 at 06:04
  • 1
    Sorry have a look at https://stackoverflow.com/questions/31626356/how-can-i-get-the-current-iana-time-zone-abbreviation-throughout-time-in-icu4j – Scary Wombat Jul 25 '17 at 06:06
  • Thank you, but should we give date long value in `getMetaZoneID(String,Long)`? Is there any other way without giving date in long? – Varshini Jul 25 '17 at 06:32
  • When you say you have time zones, have you got time zone names/IDs as strings, or `TimeZone` objects, or what? – Ole V.V. Jul 25 '17 at 07:46
  • First, you cannot. The three and four letter time zone abbreviations are not standardized and are very often ambiguous. See [this thorough answer](https://stackoverflow.com/a/18407231/5772882). – Ole V.V. Jul 25 '17 at 07:50
  • You may take a look at [`ZoneId.SHORT_IDS`](https://docs.oracle.com/javase/8/docs/api/java/time/ZoneId.html#SHORT_IDS). Even some of its conversions are controversial or at least surprising to some. – Ole V.V. Jul 25 '17 at 07:51
  • A possible near-duplicate of [Getting ZoneId from a SimpleTimeZone](https://stackoverflow.com/questions/44397874/getting-zoneid-from-a-simpletimezone). Take a look. – Ole V.V. Jul 25 '17 at 07:55
  • Thanks alot, I've read it, but it seems its nearly impossible to convert those to IANA format, right? – Varshini Jul 25 '17 at 10:05
  • 2
    As @OleV.V. told, those short names are ambiguous (IST, for example, can be India Standard Time, Irish Standard Time and Israel Standard Time, there's no way to map IST to one single timezone), so the best you can do is to get a list of candidates (IANA zones that have the same short name). Maybe [this](https://stackoverflow.com/q/44811282/7605325) can help you –  Jul 25 '17 at 11:49
  • 1
    You may also learn more from [Matt Johnson’s knowledgable answer here](https://stackoverflow.com/a/41683097/5772882). – Ole V.V. Jul 25 '17 at 12:01

1 Answers1

1

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! :-)

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • Thanks alot for your explanation :) Can we use TimeZone.getAvailableIDs() also? – Varshini Jul 26 '17 at 04:43
  • 1
    Yes you can. `TimeZone.getAvailableIDs()` contains the same IDs as `ZoneId.getAvailableZoneIds()` and in addition the 28 three letter abbreviations that you find as keys in `ZoneId.SHORT_IDS` (these 28 are not in `ZoneId.getAvailableZoneIds()`). – Ole V.V. Jul 26 '17 at 08:45