This adds the ability to guess the browser's timezone. See #138.
Demo
http://jsfiddle.net/bvjxt7jr/11/
Implementation
The implementation is fairly similar to jstimezonedetect. We look through a whitelist of zones and check if the offset matches in both January and June.
There are about 500 different timezone identifiers, and about 60 unique January/June offset pairs in use this year. The limitations of jstimezonedetect also apply here. We don't differentiate between Europe/Berlin
and Europe/Stockholm
as they are equivalent in recent years.
Whitelisted names
These are the whitelisted timezone names for each January/June offset pair.
| Jan | Jul | Timezone Name |
| --- | --- | --- |
| -11:00 | -11:00 | Pacific/Pago_Pago |
| -10:00 | -10:00 | Pacific/Honolulu |
| -10:00 | -09:00 | America/Adak |
| -09:30 | -09:30 | Pacific/Marquesas |
| -09:00 | -09:00 | Pacific/Gambier |
| -09:00 | -08:00 | America/Anchorage |
| -08:00 | -08:00 | Pacific/Pitcairn |
| -08:00 | -07:00 | America/Los_Angeles |
| -07:00 | -07:00 | America/Phoenix |
| -07:00 | -06:00 | America/Denver |
| -06:00 | -06:00 | America/Guatemala |
| -06:00 | -05:00 | America/Chicago |
| -05:00 | -05:00 | Pacific/Easter |
| -05:00 | -04:00 | America/New_York |
| -04:30 | -04:30 | America/Caracas |
| -04:00 | -04:00 | America/Santo_Domingo |
| -04:00 | -03:00 | America/Halifax |
| -03:30 | -02:30 | America/St_Johns |
| -03:00 | -04:00 | America/Campo_Grande |
| -03:00 | -03:00 | America/Santiago |
| -03:00 | -02:00 | America/Godthab |
| -02:00 | -03:00 | America/Montevideo |
| -02:00 | -02:00 | America/Noronha |
| -01:00 | -01:00 | Atlantic/Cape_Verde |
| -01:00 | +00:00 | Atlantic/Azores |
| +00:00 | +00:00 | Etc/UTC |
| +00:00 | +01:00 | Europe/London |
| +00:00 | +02:00 | Antarctica/Troll |
| +01:00 | +01:00 | Africa/Lagos |
| +01:00 | +02:00 | Europe/Berlin |
| +02:00 | +01:00 | Africa/Windhoek |
| +02:00 | +02:00 | Africa/Johannesburg |
| +02:00 | +03:00 | Asia/Beirut |
| +03:00 | +03:00 | Europe/Moscow |
| +03:30 | +04:30 | Asia/Tehran |
| +04:00 | +04:00 | Asia/Dubai |
| +04:00 | +05:00 | Asia/Baku |
| +04:30 | +04:30 | Asia/Kabul |
| +05:00 | +05:00 | Asia/Yekaterinburg |
| +05:30 | +05:30 | Asia/Kolkata |
| +05:45 | +05:45 | Asia/Kathmandu |
| +06:00 | +06:00 | Asia/Omsk |
| +06:30 | +06:30 | Asia/Rangoon |
| +07:00 | +07:00 | Asia/Krasnoyarsk |
| +07:00 | +08:00 | Asia/Hovd |
| +08:00 | +08:00 | Asia/Shanghai |
| +08:00 | +09:00 | Asia/Ulaanbaatar |
| +08:45 | +08:45 | Australia/Eucla |
| +09:00 | +09:00 | Asia/Yakutsk |
| +09:30 | +09:30 | Australia/Darwin |
| +10:00 | +10:00 | Australia/Brisbane |
| +10:30 | +09:30 | Australia/Adelaide |
| +11:00 | +10:00 | Australia/Sydney |
| +11:00 | +10:30 | Australia/Lord_Howe |
| +11:00 | +11:00 | Pacific/Noumea |
| +11:30 | +11:30 | Pacific/Norfolk |
| +12:00 | +12:00 | Pacific/Tarawa |
| +13:00 | +12:00 | Pacific/Auckland |
| +13:00 | +13:00 | Pacific/Tongatapu |
| +13:45 | +12:45 | Pacific/Chatham |
| +14:00 | +13:00 | Pacific/Apia |
| +14:00 | +14:00 | Pacific/Kiritimati |
Keeping whitelist up to date
It is likely that this list will change based on updates to the tzdb, so we will probably need a way to tie this to data updates.
One problem we will need to solve is how to determine which timezone to use in the whitelist for a given offset pair. For example, there are many timezones that match -08:00/-07:00
this year. America/Dawson
, America/Ensenada
, America/Los_Angeles
, America/Santa_Isabel
, America/Tijuana
, America/Vancouver
, America/Whitehorse
, Canada/Pacific
, Canada/Yukon
, Mexico/BajaNorte
, PST8PDT
, US/Pacific
, US/Pacific-New
.
The current whitelist is mostly based on the list from jstimezonedetect with a couple additions for new tzdb data. Ideally, we could get data for the population in each timezone and use that to choose the best candidate, but I'm not sure where we could find that data.
User added whitelisting
Because we are just looking through an array of names, we can expose that list to the user to add their own names.
moment.tz.currentZone(); // America/Chicago
moment.tz.currentZoneWhitelist.unshift('US/Central');
moment.tz.currentZone(); // US/Central
We should probably make a dedicated api for this rather than having to know the internals of whether to push or unshift onto the array.
Bikeshedding
Now the fun part.
There are a few different names we could go with here.
moment.tz.identify();
moment.tz.detect();
moment.tz.guess();
moment.tz.currentZone();
moment.tz.guessZone();
moment.tz.userZone();
To add user defined whitelisted names, we also have a couple options.
moment.tz.detect('US/Pacific'); // used as a getter/setter
moment.tz.identify('US/Pacific');
moment.tz.canDetect('US/Pacific');
moment.tz.canGuess('US/Pacific');
moment.tz.currentZoneWhitelist('US/Pacific');
moment.tz.userZoneWhitelist('US/Pacific');
New Feature