Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I don't see a way to get an easy list of the available timezones #43

Closed
hughlomas opened this issue Nov 5, 2013 · 24 comments
Closed

I don't see a way to get an easy list of the available timezones #43

hughlomas opened this issue Nov 5, 2013 · 24 comments

Comments

@hughlomas
Copy link

My use case is populating a select element with options for the available timezones so the user can set their timezone. I was hoping for something along the lines of

moment.tz.getTimezones()
which would return something like

[
    {
        name: "Eastern Standard Time"
      , locale: "America/New_York"
      , abbreviation: "EST"
      , offset: "-5"
    }
  , {
        name: "Central Standard Time"
      , abbreviation: "CST"
      , locale: "America/Chicago"
      , offset: "-6"
    }
]
@mattjohnsonpint
Copy link
Contributor

Hi. A few things:

  • The zone name is "America/New_York". That's not the locale.
  • Determining an offset and an abbreviation requires a specific point in time. It's invalid to say that "America/New_York" == -5, since in daylight time it is -4.
  • Abbreviations are somewhat ambiguous. The best we could do is return the TZDB's representation of the abbreviation, which is somewhat arbitrary and still ambiguous. For example, both America/Chicago and Asia/Shanghai use the abbreviation CST, along with several of other locations.
  • Determining a zone description such as "Eastern Standard Time" would require both a point in time, and also localization data from the CLDR which is too large for moment-timezone. For example, we might call Europe/Moscow "Moscow Standard Time" in English, but the CLDR shows us that the Russians call it "Москва, стандартное время".

So when you take all of this into consideration, the best we could do would be to spit out an array of all of the time zone names that we know about, such as ["America/Chicago","Europe/London","Africa/Johannesburg"] for example.

@hughlomas
Copy link
Author

Thank you for the response and the clarifications, my example was just a rough sketch of what was desired, pardon my misconceptions. I appreciate the work done on this library, this request should really just be considered an "enhancement" request, since it is not regarding anything wrong with moment-timezone.

I do believe that even something as simple as "an array of all of the time zone names that we know about, such as ["America/Chicago","Europe/London","Africa/Johannesburg"]" would be useful.

Regarding the offset being invalid, what about an "offset" and "offsetDST", returning, say, -5 and -4 respectively?

Regarding the descriptions such as "Eastern Standard Time", plugging "Москва, стандартное время" into Google translate outputs "Moscow Standard Time", so it appears to simply be a 1:1 translation. Perhaps the library can simply return the English description and that can be handled by however an application chooses to do localization?

Lastly, regarding any of the data that would need a "point in time" for referencing, maybe it could be an optional parameter like moment.tz.getTimezones( referenceTime ), whereas moment.tz.getTimezones() would simply base it off the current date/time.

My use case for this was simply wanting to populate a select field on a web app with a list of selectable timezones for the user. Right now I have to make my own data structure, which is not a huge deal but if I add a new timezone to the zones data passed in to moment.tz.add then I have to remember to update my reference structure as well, which is not ideal.

@mattjohnsonpint
Copy link
Contributor

Rather than using your own data structure, you could just iterate through the data in the momentTZData object. Not exactly a public API, but you should be able to reuse it.

Have you considered instead using a map-based timezone picker? They tend to work much better with end-users than drop-down lists. Take a look at this one or this one.

@msiebuhr
Copy link

As previously suggested, it sounds like you need CLDR. A colleague of mine has written a handy module for getting that data out: https://github.com/papandreou/node-cldr

(AFAIK, we generate the required client-side source-code from CLDR using this module; that way we only send the data we actually need...)

@mattjohnsonpint
Copy link
Contributor

@msiebuhr Thanks for the link! I haven't had the time to investigate CLDR for JS libraries yet, but I will take a further look at that one. Can you elaborate on that second part? Are you using this in the browser?

@msiebuhr
Copy link

We have a build-system (https://github.com/One-com/assetgraph; like these Grunt-build thingies, except it actually understands HTML, CSS, JS, ... and applies all sorts of optimizations on it) where we generate all (or: as much as we can) data like this up front. AFAIK, we don't touch CLDR once inside the browser.

@kenperkins
Copy link

This issue raises an interesting challenge: Building any app that is designed to be globally available but locally consumed will have to account for UTC to local conversion. moment-timezone seems great at the conversion, but seems to not really address configuration to a specific timezone.

@mj1856 I agree that Visual Maps can be a good way of selecting, but I'm trying to focus on building an experience that always degrades to mobile well. Neither of those two do, while a good old dropdown list with a word-wheel does.

You mentioned momentTZData but I can't find any mention of that. All I need is an Array of the timezone names as @hughlomas mentioned.

@mattjohnsonpint
Copy link
Contributor

momentTZData is created on the global scope when you call moment.tz.add(...) when establishing the time zone data. So you can examine it and pull out the keys for the time zones. Using a library like underscore.js can make this trivial:

var zones = _.keys(momentTZData.zones)

@merrihew
Copy link

I couldn't figure out how to retrieve the global momentTZData, so I created it as a global directly above the call to moment.tz.add and then referenced it. Thus, timezones load correctly and you can reference the zones object. Quick fix, but it works for now.

var momentTZData = {
        "America/Adak": [
...
moment.tz.add({
    "zones": momentTZData,
    "rules": {
...
var zones = _.keys(momentTZData)

@tschieggm
Copy link

I could not find any usage of moment.momentTZData on my local copy of moment-timezone, even after calling moment.tz.add(...). I do however see it on the http://momentjs.com/timezone/ website. I ended up doing what @merrihew suggested.

I also did a quick search and don't see any mention of momentTZData in the codebase.

@markuso
Copy link

markuso commented May 5, 2014

Here's what I do.

var timeZonesList = moment.tz.zones().map(function (zone) {
    return {
        name: zone.displayName,
        abbr: moment.tz(zone.displayName).zoneAbbr()
    };
});

@timrwood
Copy link
Member

This has been added in 0.1.0 as moment.tz.names().

http://momentjs.com/timezone/docs/#/data-loading/getting-zone-names/

@elewin
Copy link

elewin commented Mar 30, 2017

Using moment.tz.names() returns a list of over 500 elements, is it possible to condense that down so that there is just one for each zone? If this were to be used to populate a drop down to allow a user to select their timezone, then it would be completely impractical

@mattjohnsonpint
Copy link
Contributor

@elewin see #227. But also, listing out the IANA identifiers isn't so great anyway. One needs CLDR data to do it right. There's certainly room for a javascript-only version of something like my demo here.

Oh, and please don't make a habit of commenting on years-old-closed issues. ;)

@psagar5
Copy link

psagar5 commented Jul 23, 2018

@markuso - ERROR TypeError: moment.tz.zones is not a function, which version of momentjs you are using?

@markuso
Copy link

markuso commented Jul 23, 2018

@psagar5 Use the new moment.tz.names() instead for latest version. See the comment right after my old one here. I have switched to that. So you don't need my solution anymore. The underscore _ is the reference to lodash, but I changed my old comment right now to use plain JS .map() method.

@psagar5
Copy link

psagar5 commented Jul 23, 2018

@markuso - i am getting list either 592 or 365 (if i filter out) entries for moment.tz.names(). Is there any way to use standard timezones, smaller list?
I guess there are 37 standard timezones.

@psagar5
Copy link

psagar5 commented Jul 25, 2018

@markuso - please let me know if there is any way to filter the list to get less than 50 timezones?

@markuso
Copy link

markuso commented Jul 25, 2018

@psagar5 I am not aware of any smaller list or a specific way to filter the list to some sort of standard short list. To cover worldwide time zones, you need the full list. In our application, we just show the full list to our users grouped by the first section of each name. Like "America" heading for all the "America/***" zones, etc.

Sorry, maybe someone else could have a better answer about a standard short list you speak of.

@elewin
Copy link

elewin commented Aug 2, 2018

What we ended up doing was mapping the IANA time zones to Windows time zones, then we let the user select a windows time zone to narrow things down, then drill down further and list all the IANA time zones that fall under it so they can select the IANA time zone that applies specifically to them. It is much easier to quickly narrow down the time zones you present to the user that way.

@psagar5
Copy link

psagar5 commented Aug 8, 2018

@elewin - can you share code snippet of your implementation?

@elewin
Copy link

elewin commented Aug 13, 2018

@psagar5 Sure,
So first we create a big array of objects, each object is a Windows time zone. Within each object, it then has its own array of IANA time zones that map to it

 [
// . . .
   {
   "value": "Pacific Standard Time",
   "abbr": "PDT",
   "offset": -7,
   "isdst": true,
   "text": "(UTC-08:00) Pacific Time (US & Canada)",
   "utc": [
     "America/Dawson",
     "America/Los_Angeles",
     "America/Tijuana",
     "America/Vancouver",
     "America/Whitehorse",
     "PST8PDT"
   ]
 }, {
   "value": "US Mountain Standard Time",
   "abbr": "UMST",
   "offset": -7,
   "isdst": false,
   "text": "(UTC-07:00) Arizona",
   "utc": [
     "America/Creston",
     "America/Dawson_Creek",
     "America/Hermosillo",
     "America/Phoenix",
     "Etc/GMT+7"
   ]
 }, {
   "value": "Mountain Standard Time (Mexico)",
   "abbr": "MDT",
   "offset": -6,
   "isdst": true,
   "text": "(UTC-07:00) Chihuahua, La Paz, Mazatlan",
   "utc": [
     "America/Chihuahua",
     "America/Mazatlan"
   ]
 }, {
   "value": "Mountain Standard Time",
   "abbr": "MDT",
   "offset": -6,
   "isdst": true,
   "text": "(UTC-07:00) Mountain Time (US & Canada)",
   "utc": [
     "America/Boise",
     "America/Cambridge_Bay",
     "America/Denver",
     "America/Edmonton",
     "America/Inuvik",
     "America/Ojinaga",
     "America/Yellowknife",
     "MST7MDT"
   ]
 },
// . . .
]		

Then, on the UI we have a drop-down that shows the text property of each element of the above array of Windows time zones, and when the user selects one of those, a second part of the UI then displays the array of IANA time zones (the utc array in the selected object) and then the user can select the specific time zone that belongs to them.

I don't remember where we got that map of time zones from though; I can't recall if its something that we compiled our self or if it's from some other open source project; if its from another open source project then apologies to whoever wrote it, at the moment I can't find the original link where its from to give proper credit :(

@stasinua
Copy link

@elewin Maybe this one:
https://github.com/dmfilipenko/timezones.json

@Dipesh-Das97
Copy link

Hi, is there a way to get the list of common timezones alone, just as pytz.common_timezones(basically just sends a list of timezones which are commonly used other than UTC as well as maintains the non deprecated list)? This is something I have looked for sometime but had no luck. Any ideas?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests