I am attempting to find a user-friendly list of time zones for users to select their current time zone. It would have common names that time zones that are referred to such as Pacific Time (US and Canada).
This list should map the text to an IANA standard name such as America/Los_Angeles.
It would also remove listings that the user thinks of as the "same" time zone. For example the listing for Pacific Time (US and Canada) would correspond to America/Los_Angeles and America/Tijuana, which are the "same" time.
I've tried looking in the IANA Time Zone Database, ECMA Script internationalization API, and libraries like Moment.js. They can parse the IANA name into the common name, for example America/Los_Angeles
==> "Pacific Standard Time"
but don't have a built-in function for listing all the common names and their corresponding IANA names.
The tz database is also known as tzdata, the zoneinfo database or IANA time zone database, and occasionally as the Olson database, referring to the founding contributor, Arthur David Olson.
There are total of 422 time zones listed.
Reference to a specific time and zone would follow standard guidelines with the zone in parentheses: 4:42 p.m. (PST), 11:03 a.m. (MDT), 2:30 p.m. (CST), 10:00 P.M. (EST). AP on the other hand advises to capitalize the full name of each time zone: Pacific/Mountain/Central/Eastern Standard Time.
You can use Intl.DateTimeFormat.prototype.formatToParts()
.
new Intl.DateTimeFormat(
'default',
{ timeZone: 'America/Los_Angeles', timeZoneName: 'long' }
).formatToParts().find(({ type }) => type === 'timeZoneName').value
// 'Pacific Daylight Time'
The short answer is there is no simple map from IANA representative location names to common names because the IANA name doesn't reflect historic changes in offset or daylight saving, nor are common names sufficiently standardised either officially or de facto.
IANA representative locations include historic changes in timezone offset, both for the local time and daylight saving as it has been applied over the years. The standard timezone name probably hasn't changed, however the offsets have and continue to. Also, the IANA representative location name stays the same during daylight saving, however the offset and common name don't.
E.g. Samoa has an IANA name of "Pacific/Samoa". Its standard offset prior to 29 December 2011 was UTC−11:00 but after then its offset has been UTC+13:00, and its daylight saving time went from UTC-1000 to UTC+14:00. The common names for its timezone are "Samoa Standard Time" and "Samoa Daylight Saving Time", however these names aren't standardised and in many places are ambiguous (e.g. CST might be central standard time in 2 or 3 different places, or China standard time).
So there is no simple map from IANA representative location name to common timezone name for all IANA locations. You may be able to create one for a small subset, however using the built–in Intl object is likely simpler, e.g.
let opts = {
hour: 'numeric',
minute:'2-digit',
timeZone: 'Pacific/Samoa',
timeZoneName: 'long'
};
let time = new Date().toLocaleString('en', opts);
console.log('Currently in Samoa it\'s ' + time);
On the latest version of MacOS, the above gives an offset for Samoa of UTC-1100 so still using old values, and it doesn't recognise daylight saving so the Intl object can't be relied upon.
You might use the Intl object as below, noting that for some locations it may not have a name for the timezone, so just shows the offset (e.g. try Europe/Astrakhan). There are nearly 600 IANA locations.
// Detect user representative location if available
let repLoc = (typeof Intl == 'object' &&
typeof Intl.DateTimeFormat == 'function' &&
typeof Intl.DateTimeFormat().resolvedOptions == 'function')?
Intl.DateTimeFormat().resolvedOptions().timeZone : 'default';
function setRepLoc(evt) {
showSampleDates(this.value);
}
function showSampleDates(repLoc) {
let el0 = document.getElementById('sDate0');
let el1 = document.getElementById('sOff0');
let el2 = document.getElementById('sDate1');
let el3 = document.getElementById('sOff1');
let d0 = new Date(Date.UTC(2020,0,1,11));
let d1 = new Date(Date.UTC(2020,5,1,11));
let opts = {
weekday: 'short',
day: 'numeric',
month: 'short',
year: 'numeric',
hour: 'numeric',
minute: '2-digit',
timeZone: repLoc,
timeZoneName: 'long'
};
let offOpts = {
hour: 'numeric',
hour12: false,
timeZone: repLoc,
timeZoneName: 'short'
}
if (repLoc == 'default') {
el0.textContent = '';
el1.textContent = '';
el2.textContent = '';
el3.textContent = '';
} else {
el0.textContent = d0.toLocaleString('en-NZ', opts);
el1.textContent = d0.toLocaleString('en-NZ', offOpts).split(' ')[1];
el2.textContent = d1.toLocaleString('en-NZ', opts);
el3.textContent = d1.toLocaleString('en-NZ', offOpts).split(' ')[1];
}
}
window.onload = function(){
let sel = document.getElementById('repLoc')
if (repLoc) {
sel.options[0].text = repLoc;
sel.options[0].value = repLoc;
sel.selectedIndex = 0;
setRepLoc.call(sel);
}
sel.addEventListener(
'change',
setRepLoc,
false);
};
td:nth-child(1){text-align:right;color:#999;}
td:nth-child(2){font-family:monospace}
<table>
<tr>
<td>IANA loc:
<td><select id="repLoc">
<option selected value="default">Select a location
<option>Europe/Amsterdam
<option>Europe/Andorra
<option>Europe/Astrakhan
<option>Europe/Athens
<option>Europe/Belfast
<option>Pacific/Samoa
<option>Pacific/Kiritimati
<option>Antarctica/DumontDUrville
<option>Antarctica/Davis
<option>America/Chicago
<option>Australia/Brisbane
</select>
<tr>
<td>Sample:
<td id="sDate0">
<tr>
<td>Offset:
<td id="sOff0">
<tr>
<td>Sample:
<td id="sDate1">
<tr>
<td>Offset:
<td id="sOff1">
</table>
Building on Kimamula's answer, I took the current list of IANA time zone names and ran it through my browser's Intl formatter to obtain long and short names for all of them. The result is a gist with a mapping of IANA names to human readable names. I've taken the 'generic' forms of these names, which omits mention of daylight saving time. Otherwise we would need to know whether DST is in effect to select the name. (e.g. Pacific Time instead of Pacific Standard Time or Pacific Daylight Time).
Not every timezone has an ideal name in this database, as with most things time related this will be an imperfect solution. But it will hopefully cover the time zones that are most popular with your users, and displaying an IANA name as a fallback is an option.
In case you want to generate these names yourself, you can run this in your browser. These names came from Firefox, I would guess that they are implementation dependent and might be a bit different in other browsers.
const iana_names = [
"Africa/Abidjan",
"Africa/Accra",
"Africa/Addis_Ababa",
// ...
"W-SU",
"WET",
"Zulu"
]
const mapping = {}
iana_names.forEach( name => {
const long = new Intl.DateTimeFormat('default', { timeZone: name, timeZoneName: 'longGeneric' }).formatToParts().find(({ type }) => type === 'timeZoneName').value
const short = new Intl.DateTimeFormat('default', { timeZone: name, timeZoneName: 'shortGeneric' }).formatToParts().find(({ type }) => type === 'timeZoneName').value
mapping[name] = {
long, short
}
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With