What are the "standard" timezone abbreviations?

I am storing time zone by offset-from-UTC for an application using this dropdown:

<select id="timezone" name="timezone" >
<option value="-12">[UTC - 12] Baker Island Time</option>
<option value="-11">[UTC - 11] Niue Time, Samoa Standard Time</option>
<option value="-10">[UTC - 10] Hawaii-Aleutian Standard Time, Cook Island Time</option>
<option value="-9.5">[UTC - 9:30] Marquesas Islands Time</option>
<option value="-9">[UTC - 9] Alaska Standard Time, Gambier Island Time</option>
<option value="-8">[UTC - 8] Pacific Standard Time</option>
<option value="-7">[UTC - 7] Mountain Standard Time</option>
<option value="-6">[UTC - 6] Central Standard Time</option>
<option value="-5">[UTC - 5] Eastern Standard Time</option>
<option value="-4.5">[UTC - 4:30] Venezuelan Standard Time</option>
<option value="-4">[UTC - 4] Atlantic Standard Time</option>
<option value="-3.5">[UTC - 3:30] Newfoundland Standard Time</option>
<option value="-3">[UTC - 3] Amazon Standard Time, Central Greenland Time</option>
<option value="-2">[UTC - 2] Fernando de Noronha Time, South Georgia &amp; the South Sandwich Islands Time</option>
<option value="-1">[UTC - 1] Azores Standard Time, Cape Verde Time, Eastern Greenland Time</option>
<option value="0">[UTC] Western European Time, Greenwich Mean Time</option>
<option value="1">[UTC + 1] Central European Time, West African Time</option>
<option value="2">[UTC + 2] Eastern European Time, Central African Time</option>
<option value="3">[UTC + 3] Moscow Standard Time, Eastern African Time</option>
<option value="3.5">[UTC + 3:30] Iran Standard Time</option>
<option value="4">[UTC + 4] Gulf Standard Time, Samara Standard Time</option>
<option value="4.5">[UTC + 4:30] Afghanistan Time</option>
<option value="5">[UTC + 5] Pakistan Standard Time, Yekaterinburg Standard Time</option>
<option value="5.5">[UTC + 5:30] Indian Standard Time, Sri Lanka Time</option>
<option value="5.75">[UTC + 5:45] Nepal Time</option>
<option value="6">[UTC + 6] Bangladesh Time, Bhutan Time, Novosibirsk Standard Time</option>
<option value="6.5">[UTC + 6:30] Cocos Islands Time, Myanmar Time</option>
<option value="7">[UTC + 7] Indochina Time, Krasnoyarsk Standard Time</option>
<option value="8">[UTC + 8] Chinese Standard Time, Australian Western Standard Time, Irkutsk Standard Time</option>
<option value="8.75">[UTC + 8:45] Southeastern Western Australia Standard Time</option>
<option value="9">[UTC + 9] Japan Standard Time, Korea Standard Time, Chita Standard Time</option>
<option value="9.5">[UTC + 9:30] Australian Central Standard Time</option>
<option value="10">[UTC + 10] Australian Eastern Standard Time, Vladivostok Standard Time</option>
<option value="10.5">[UTC + 10:30] Lord Howe Standard Time</option>
<option value="11">[UTC + 11] Solomon Island Time, Magadan Standard Time</option>
<option value="11.5">[UTC + 11:30] Norfolk Island Time</option>
<option value="12">[UTC + 12] New Zealand Time, Fiji Time, Kamchatka Standard Time</option>
<option value="12.75">[UTC + 12:45] Chatham Islands Time</option>
<option value="13">[UTC + 13] Tonga Time, Phoenix Islands Time</option>
<option value="14">[UTC + 14] Line Island Time</option>

Using PHP, I don't really have the easiest options to convert these to timezone abbreviations, my only option to do it programmatically would be to sort through a list of about 400 timezone abbreviations. Does anyone know the list that goes along with this dropdown of what each of the timezones are, and what they are when daylight savings is going on? (I assume I need to define both lists manually)

EDIT: parsed this list down to a single abbr for each timezone, but they arent the "popular" ones.

My new list

[-12] => kwat
[-11] => bst
[-10] => ahst
[-9.5] => ckhst
[-9] => ahdt
[-8] => akdt
[-7] => east
[-6] => cst
[-5] => act
[-4.5] => ant
[-4] => acst
[-3.5] => negt
[-3] => adt
[-2] => addt
[-1] => azost
[-0] => azomt
[1] => bst
[2] => bdst
[3] => amt
[3.5] => irst
[4] => adt
[4.5] => aft
[5] => aktt
[5.5] => ist
[5.75] => npt
[6] => aktst
[6.5] => burt
[7] => almst
[8] => bnt
[8.75] => cwst
[9] => cdt
[9.5] => cast
[10] => chost
[10.5] => cst
[11] => anat
[11.5] => lhst
[12] => anast
[12.75] => chast
[13] => anast
[14] => anast

Code:

$abbr = DateTimeZone::listAbbreviations();

$offsets=array('-12','-11','-10','-9.5','-9','-8','-7','-6',
    '-5','-4.5','-4','-3.5','-3','-2','-1','-0','1','2','3','3.5',
    '4','4.5','5','5.5','5.75','6','6.5','7','8','8.75','9','9.5',
    '10','10.5','11','11.5','12','12.75','13','14');
$new = array();
$count = 0;
$found = false;
while($count < count($offsets))
{
    foreach($abbr as $k => $v)
    {
        foreach($v as $tz)
        {
            if($tz['offset'] == $offsets[$count]*3600)
            {
                $new[$offsets[$count]] = $k;
                $found = true;
                break;
            }
        }
        if($found)
        {
            $found = false;
            break;
        }
    }
    $count++;
}
print_r($new);

Solution 1:

What are the "standard" timezone abbreviations?

There are no standards for this. Time zone abbreviations are not officially coordinated by anyone. There are some used in the IANA TZDB, but a lot of those were just chosen at random. There is often debate on which abbreviations should be used. For example, look how many posts there were about Australian abbreviations in the list archives for April 2013.

Another list of time zone abbreviations can be found here. If you look closely, you'll see that many are ambiguous. For example, CST could be "Central Standard Time" (USA), "China Standard Time", or "Cuba Standard Time". EST could be "Eastern Standard Time" (USA), or "Eastern Standard Time" (Australia).

Some non-Australians might prefer AEST, but who's to say that A should be for Australia and not for America?

Another very common example, some people use HAST for Hawaii, while others use HST because they could care less about the Aleutian islands in Alaska (which is what the A is supposed to represent).

The point is that any list of time zone abbreviations, anywhere you find one, will be subjective and opinionated. There is no standard.

I am storing timezone by offset for an application using this dropdown:

Please don't do that. A time zone is not an offset, and there are many more than 24 of them. Please read the timezone tag wiki, especially the section titled "Time Zone != Offset".

From your comments:

I realize this now, however the rest of my application logic depends on it this way already, and I only have today to complete this, so no time to change it.

Then many errors will continue to be present in your application. You just can't do this reliably - not even if your app just runs in the US. It doesn't matter what language or platform you are on, any implementation that does this will have lots of conversion mistakes.

I'm ok with hardcoding these arrays, I just don't know what the popular zones are outside of the US, I figured such a list would already exist somewhere.

When it comes to time zones, you shouldn't hard-code anything. Time zone rules change all the time, because they are controlled by politicians in every country of the world. There are updates released multiple times per year to the IANA time zone database. On the PHP side, the PHP documentation makes clear what version currently available, and that updates are handled via PECL's timezonedb - which pulls it's data from IANA.

In regards to what's "popular" - that is highly subjective also. The zones in the TZDB are all there for one reason or another. The only place I know that has attempted to limit this is ActiveSupport::TimeZone from Ruby on Rails. They claim to have a "meaningful subset of 146 zones", which you can see in the MAPPING constant on that page. But they don't say by what process they've decided what is considered meaningful, and there are clear omissions. Unless you know for a fact where each and every one of your users will be located, I wouldn't attempt to decide what zones to limit to.

If what your after is something other that a dropdown list of all 578 zones in the TZDB, you can try one of these approaches:

  • Present two drop downs. The first to select a country. The second to choose a zone within that country. In PHP, you can see that when you call DateTimeZone::listIdentifiers, it accepts an optional $country parameter to filter the list.

    A good example of this is in the settings for Google Calendar:

    Google Calendar Time Zone Settings

  • Use a map-based control so your user can select their time zone by location. There are many of these out there, but my favorite is this one for JavaScript.

    For example, it might look like this:

    Map-based TZ picker

Note that while it shows the TZDB abbreviation of EDT here - that is just used for a display convenience. Under the hood, you are selecting a value like America/New_York.

Ultimately, what you need to save for each user is their IANA time zone key, such as America/New_York. You cannot do correct time zone conversions with just a value of -5, because you don't have all of the rules of when it will switch to -4.

Update

One thing I didn't realize from your original post, but you clarified in comments, is that you are using this to choose a target event time zone. I guess I should have asked for context first. I was approaching this from the perspective of choosing a single time zone for your user, rather than a specific time zone for a particular event.

All you really need for an event to be at the correct moment is the offset for that moment. So you could use a dropdown like the one you showed in your question - but I would omit any zone names. It would litterally be a list of offsets from UTC-12:00 to UTC+14:00. It looks like you have identified already that some 30-minute and 45-minute offset exists also. You can verify your assumptions here if you like.

The general problem though, is that many people don't know what the offset should be. By putting a list with the standard offset for each zone name, you might mislead the user into picking the wrong offset. For example, they might be talking about a date in the summer that should fall into US Eastern Daylight Time (-4), but they pick the -5 selection instead because they see "Eastern". So removing the names will help.

If you go the way I originally suggested and have them pick an actual IANA time zone, that is going to work much better for many scenarios. However there is still one scenario you need to think about - how to handle ambiguous and invalid times. These happen during the DST transitions.

For example, I might select America/New_York, and pick a time of 1:00 AM on November 3rd 2013. There are two different instances of that due to the fall-back transition (one in EDT at -4 and another in EST at -5). So your app would need to check for this and ask the user which of the two they meant. Likewise, if I enter 2:00 AM on March 10th 2013, your app should tell me that this time does not exist in that zone (due to the spring-forward transition).

With either approach, when it comes to actually storing the event times, make sure you either store the date-time-offset combination, or you apply the offset to get a date-time that is at UTC. You don't want there to be any question about what actual moment in time is represented by the event.