I am storing time zone by offset-from-UTC for an application using this dropdown:
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:
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:
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.