Mapping IANA/Olson timezone database to abbreviations (like EST, PST, etc) - timezone

I need to map IANA/Olson timezone id to abbreviations, like EST, PST, etc.
I understand that this is not 1-to-1 mapping and that, for example, for EST there are quite a bunch of IANA timezones.
Is there some kind of database/mapping I can use for this?
PS: JavaScript solution is preferable, but any info that could help me to build this mapping (IANA timezone id -> abbreviation) is appreciated.

The IANA TZDB source data does have abbreviations already, but they have to be computed for the date in question. You can see it in the example data here, in the Zone.FORMAT and Rule.LETTER/S columns.
Since time zone abbreviations like CST can be ambiguous, it is only recommended you use them for display to a human. Never attempt to use them going the other direction, because only a few will be recognized by most implementations, and they tend to be valid only for the USA.
Since you asked for code that could do this for you, look at the bottom half of the code in my answer of how to do this using Noda Time in .Net. (The top half is about translating from a Windows zone to an IANA zone first, which you don't need.)
You could look at one of the several TZDB libraries for JavaScript, but I'm not sure if any directly expose the abbreviation data or not. Besides, that's a bit heavy for something so small.

In java with joda-time, we can get time-zone abbreviation from iana id as below
DateTimeZone dz = DateTimeZone.forID("America/New_York");
String tzid = dz.getShortName(DateTimeUtils.currentTimeMillis());
//tzid will be 'EST'
String longerTimeZoneName = dz.getName(DateTimeUtils.currentTimeMillis());
//longerTimeZoneName will be 'Eastern Standard Time'

Related

Joda DateTimeFormatter.parseDateTime is failing for General time zone('z')

Confused with the use of General time zone('z'). Joda is failing in below sample code. Can somebody help me to understand why the behavior is like this? How can I parse a date in differnt timezone using this format in Joda?
public static void main(String[] args) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z");
System.out.println(sdf.parse("2019.09.17 AD at 15:29:00 IST"));
DateTimeFormatter pattern = DateTimeFormat.forPattern("yyyy.MM.dd G 'at' HH:mm:ss z");
DateTime dateCtxParamDateTimeObj = pattern.parseDateTime("2019.09.17 AD at 15:29:00 IST");
System.out.println(dateCtxParamDateTimeObj.toDate());
}
Output
Tue Sep 17 15:29:00 IST 2019
Exception in thread "main" java.lang.IllegalArgumentException: Invalid format: "2019.09.17 AD at 15:29:00 IST" is malformed at "IST"
at org.joda.time.format.DateTimeFormatter.parseDateTime(DateTimeFormatter.java:945)
Edit: You need to tell Joda-Time what you mean by IST
Thanks go to HarryQ, who pointed me here to where this is documented.
DateTimeUtils.setDefaultTimeZoneNames(Collections.singletonMap(
"IST", DateTimeZone.forID("Europe/Dublin")));
DateTimeFormatter pattern = DateTimeFormat.forPattern("yyyy.MM.dd G 'at' HH:mm:ss z");
DateTime dateCtxParamDateTimeObj = pattern.parseDateTime("2019.09.17 AD at 15:29:00 IST");
System.out.println(dateCtxParamDateTimeObj);
The output from this snippet is:
2019-09-17T15:29:00.000+01:00
Lowercase z in a format pattern string works differently when formatting and when parsing in Joda-Time. Joda-Time can format time zone names for all available time zones, but with default settings it can only parse a few back. Which it can parse is controlled by the default time zone names of the DateTimeUtils class. It comes with a map of 10 time zone abbreviations as documented in the DateTimeUtils.getDefaultTimeZoneNames method (link at the bottom): CST, MDT, GMT, PST, PDT, UTC, EDT, CDT, EST and MST. We can substitute with a different map. What I am doing above is substituting with a map of just one abbreviation for the illustration. This risks breaking other code, so a better approach for most purposes would be to build a map containing both the abbreviations that were there before and that or those that we want to be able to parse too.
The map I provided above assumes that IST is for Irish Summer Time (and on September 17, 2019, Ireland was using summer time (DST)). You hardly meant Israel Standard Time because Israel too used summer time, IDT. A third likely understanding is India Standard Time:
DateTimeUtils.setDefaultTimeZoneNames(Collections.singletonMap(
"IST", DateTimeZone.forID("Asia/Kolkata")));
2019-09-17T15:29:00.000+05:30
You notice that we now get offset +05:30 instead of +01:00, so a different point in time. The ambiguity may also be the reason why Joda-Time refuses to make its own assumption about what you intended and therefore needs us to tell it before it can parse the string.
Original answer
It’s a documented limitation in Joda-Time. From the documentation of DateTimeFormat:
Zone names: Time zone names ('z') cannot be parsed.
Also note that IST and many other time zone abbreviations are ambiguous, so if there is any way you can avoid parsing one, by all means do avoid it. IST may be for Irish Summer Time, Israel Standard Time or India Standard Time, and there’s no guarantee which of them you get, or if you may even get Iceland Standard Time.
If you insist, one possible solution is to follow the advice from the Joda-Time homepage:
Note that Joda-Time is considered to be a largely “finished” project.
No major enhancements are planned. If using Java SE 8, please migrate
to java.time (JSR-310).
The DateTimeFormatter class of java.time (the modern Java date and time API) will attempt to parse a time zone abbreviation. Good luck.
Links
Joda-Time
Documentation of DateTimeUtils.getDefaultTimeZoneNames()
Related question: Why Joda DateTimeFormatter cannot parse timezone names ('z')
Documentation of DateTimeFormat
Joda-Time homepage
SO user HarryQ, who in comments under my answer to this duplicate question pointed me to the documentation of Joda-Time’s default time zone names.
Others
My answer here shows how to control the interpretation of IST while parsing when using java.time.

Time zones `Etc/GMT`, why it is other way round?

Time zones in php work like this https://www.gsp.com/support/virtual/admin/unix/tz/gmt/
and when it named Etc/GMT+11 it actually GMT-11
and when it named Etc/GMT-11 it actually GMT+11
Why? And what does it mean Etc/GMT?
I find it in PHP, is it a bug in PHP or is it everywhere?
This is not a bug. The tz database identifiers of the form Etc/GMT±* deliberately have an inverted sign than the usual forms we expect under ISO 8601. That is, they are in terms of positive values being West of GMT, rather than positive values being East of GMT.
The reason is for backwards compatibility with POSIX style time zone identifiers, such as are used with the first format of the TZ environment variable. When POSIX compliant systems interpret this variable, values like America/Los_Angeles would clearly fall through to the third format (described in the same document), but values like Etc/GMT+11 are ambiguous as to which format rules should apply. Thus the zone identifiers must have their signs inverted to be compliant.
From the tz database where these zones are defined:
# Be consistent with POSIX TZ settings in the Zone names,
# even though this is the opposite of what many people expect.
# POSIX has positive signs west of Greenwich, but many people expect
# positive signs east of Greenwich. For example, TZ='Etc/GMT+4' uses
# the abbreviation "-04" and corresponds to 4 hours behind UT
# (i.e. west of Greenwich) even though many people would expect it to
# mean 4 hours ahead of UT (i.e. east of Greenwich).
This is also discussed in the Wikipedia article on the tz database.
As far as practical matters, the tz database commentary also says:
# These entries are mostly present for historical reasons, so that
# people in areas not otherwise covered by the tz files could "zic -l"
# to a time zone that was right for their area. These days, the
# tz files cover almost all the inhabited world, and the only practical
# need now for the entries that are not on UTC are for ships at sea
# that cannot use POSIX TZ settings.
So, if you're not keeping time for ships at sea, I highly suggest you use a locality based identifier instead. (perhaps Australia/Melbourne ?)
Also, A better source of time zone identifiers would be the one on Wikipedia.
Since you said you were using PHP note that the PHP documentation has a list as well, and on the "Others" page, it actually explains this as well:
Warning
Please do not use any of the timezones listed here (besides UTC), they only exist for backward compatible reasons, and may expose erroneous behavior.
Warning
If you disregard the above warning, please also note that the IANA timezone database that provides PHP's timezone support uses POSIX style signs, which results in the Etc/GMT+n and Etc/GMT-n time zones being reversed from common usage.
For example, the time zone 8 hours ahead of GMT that is used in China and Western Australia (among other places) is actually Etc/GMT-8 in this database, not Etc/GMT+8 as you would normally expect.
Once again, it is strongly recommended that you use the correct time zone for your location, such as Asia/Shanghai or Australia/Perth for the above examples.

xpages and time zone

I am building apps that support users spread across multiple countries / time zones. I had two questions with timezone manipulations in xpages. Please share any tips you have to make this easier to code and maintain.
Time zone list
In notes client and traditional domino web design we have a standard timezone control that lists exhaustive timezone options. With xpages, we do not have any such control and have to resort to maintaining some config based static list on our own. This is not very desirable as it does not update when DST rules change for countries or new time zones are introduced. These apps may also be accessed via notes client so we cannot really use java tz format, it should be the notes TZ constant (Z=6$DO..).
Is there a way to show a dynamic list of notes timezone options?
Time zone conversion (notes/java)
How do you convert a notes timezone constant into its java equivalent and vice-versa?
Scenario:
If a user in North America wants to know the current time in a different timezone, say X. Where X is stored in the current notes document. Can you do this conversion using SSJS code?
Currently, we are using #Texttotimeinzone and evaluating it (#Texttotimeinzone is not a SSJS function). Is there a simpler way to convert a notes tz constant to java so we can perform all date conversions using java classes?
The teamroom template that ships with the ExtLib has a calendar that has the option to create a meeting and specify the time zone.
check out the custom control "controlSectionTimezonePicker". It might not be exactly what your looking for but should be a good start as a working example.
You can include the time zone information along with the date.
Initialise the date variable and use .toString() (link to documentation)
Or you can compute it in a field with JS like
var d=new Date();
d.toString()
Instead of .toString(), you can use .toUTCString().

Are 'US/Eastern' and 'US/Central' and 'US/Pacific' deprecated for strftime or just PHP?

I have a shell script (zsh, to be precise) which uses
strftime "%I:%M %p %Z (%a, %b %d)" "$EPOCHSECONDS"
to generate a "current time" such as
"02:45 PM CST (Thu, Mar 01)"
This needs to be able to display the time in several different USA timezones, and so I have been using 'US/Eastern', 'US/Central', and 'US/Pacific' like so:
export TZ='US/Eastern'
strftime "%I:%M %p %Z (%a, %b %d)" "$EPOCHSECONDS"
That seems to work just fine, and I prefer it to using TZ='America/CityName' because it doesn't require me to know which city is in which TZ, I just need to tell it which TZ I want.
However, I happened across http://www.php.net/manual/en/timezones.others.php and saw that it says
Please do not use any of the timezones listed here (besides UTC),
they only exist for backward compatible reasons.
I don't know what the issues are with the US/Region names, but I'm curious to know if using them is likely to cause a problem in the foreseeable future, or are they still safe to use? Is it just PHP which doesn't like them, or is everyone moving away from them?
The standard format for naming timezones in the Olson database is Continent/City. The "old" names you mention like US/Eastern, US/Central, and many more, are listed as backward compatibility links in the tzdata source distribution (in the file "backward"). According to the comment at the top of the file, these names may have become backward compatibility links in late 1993.
I think I remember reading that this standard was adopted because it was felt to be more stable: geopolitical (country) boundaries change, cities never move around. Maybe also because names like "Eastern" and "Central" are thought to be more confusing because they mean different timezones in different parts of the world. However, I cannot find any references to the naming rationale at the moment, so don't quote me on this.
The Continent/City-style names are preferred. Notice that operating systems like Debian and Ubuntu ask you to select the system timezone using these names (unless they autodetect it at installation time), Using these names you wouldn't really be required to, as you say, "know which city is in which TZ" because the city name is, well, part of the timezone name! So if you happen to have learned the Continent/City names instead of or in addition to the Country/Region names, you're already OK.
That being said, I do not think that these names will ever disappear. On the timezone mailing list, they are definitely always called "backward compatibility", not "deprecated", and are intended to stay, notwithstanding what PHP recommends.

Convert to CST Using Joda API

Any one know how to convert UTC time to CST time using joda date time api ?
My code is something like this.
DateTimeZone zone = DateTimeZone.forID("CST");
DateTime mstTime = utcDateTime.toDateTime(zone);
Api says 'The datetime zone id CST is not recognised'
Short time-zone ids like "CST" are unclear and ambiguous, so they are not supported. Use a longer form, like "America/New_York".
Some of the three-letter time zones (EST and MST, for example) are included in the default time zone database used by Joda. Others (CST and PST, for example) are not. (See http://joda-time.sourceforge.net/timezones.html for more details.)
The time zone IDs supported by Joda can be obtained by calling org.joda.time.DateTimeZone.getAvailableIDs(), and that set does differ from those returned by java.util.TimeZone.getAvailableIDs().
You can use "CST6CDT" format of joda time.

Resources