与 IANA 名称相对应的用户友好时区名称

nth*_*ild 7 javascript datetime momentjs ecmascript-6

我试图找到一个用户友好的时区列表,供用户选择他们当前的时区。它将具有所引用的时区的通用名称,例如 太平洋时间(美国和加拿大)

此列表应将文本映射到 IANA 标准名称,例如America/Los_Angeles

它还会删除用户认为“相同”时区的列表。例如,太平洋时间(美国和加拿大)的列表将对应于 America/Los_Angeles 和 America/Tijuana,它们是“相同”时间。

我尝试查看IANA 时区数据库ECMA 脚本国际化 API以及Moment.js等库。他们可以将 IANA 名称解析为通用名称,例如America/Los_Angeles==>"Pacific Standard Time"但没有内置函数来列出所有通用名称及其对应的 IANA 名称。

Rob*_*obG 4

简而言之,没有从 IANA 代表位置名称到通用名称的简单映射,因为 IANA 名称不反映偏移量或夏令时的历史变化,通用名称也没有在官方或事实上得到充分标准化

\n

长答案

\n

IANA 代表地点包括时区偏移的历史性变化,包括多年来一直应用的当地时间和夏令时。标准时区名称可能没有改变,但偏移量已经改变并且继续改变。此外,IANA 代表位置名称在夏令时期间保持不变,但偏移量和通用名称则不然。

\n

例如,萨摩亚的 IANA 名称为“太平洋/萨摩亚”。2011 年 12 月 29 日之前的标准偏移量为 UTC\xe2\x88\x9211:00,但此后其偏移量为 UTC+13:00,夏令时从 UTC-1000 变为 UTC+14:00。其时区的通用名称是“萨摩亚标准时间”和“萨摩亚夏令时”,但是这些名称没有标准化,并且在许多地方不明确(例如,CST 可能是 2 或 3 个不同地方的中央标准时间,或者中国标准时间)。

\n

因此,不存在从 IANA 代表位置名称到所有 IANA 位置的通用时区名称的简单映射。您也许可以为一小部分创建一个,但是使用built\xe2\x80\x93in Intl 对象可能更简单,例如

\n

\r\n
\r\n
let opts = {\n  hour: \'numeric\',\n  minute:\'2-digit\',\n  timeZone: \'Pacific/Samoa\',\n  timeZoneName: \'long\'\n};\nlet time = new Date().toLocaleString(\'en\', opts);\nconsole.log(\'Currently in Samoa it\\\'s \' + time);
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

笔记

\n

在最新版本的 MacOS 上,上面给出了萨摩亚的 UTC-1100 偏移量,因此仍然使用旧值,并且它不识别夏令时,因此不能依赖 Intl 对象。

\n

您可以按如下方式使用 Intl 对象,请注意,对于某些位置,它可能没有时区名称,因此仅显示偏移量(例如尝试欧洲/阿斯特拉罕)。IANA 有近 600 个地点。

\n

\r\n
\r\n
// Detect user representative location if available\nlet repLoc = (typeof Intl == \'object\' && \n              typeof Intl.DateTimeFormat == \'function\' &&\n              typeof Intl.DateTimeFormat().resolvedOptions == \'function\')?\n              Intl.DateTimeFormat().resolvedOptions().timeZone : \'default\';\n\nfunction setRepLoc(evt) {\n  showSampleDates(this.value);\n}\n\nfunction showSampleDates(repLoc) {\n  let el0 = document.getElementById(\'sDate0\');\n  let el1 = document.getElementById(\'sOff0\');\n  let el2 = document.getElementById(\'sDate1\');\n  let el3 = document.getElementById(\'sOff1\');\n\n  let d0 = new Date(Date.UTC(2020,0,1,11));\n  let d1 = new Date(Date.UTC(2020,5,1,11));\n  let opts = {\n    weekday: \'short\',\n    day: \'numeric\',\n    month: \'short\',\n    year: \'numeric\',\n    hour: \'numeric\',\n    minute: \'2-digit\',\n    timeZone: repLoc,\n    timeZoneName: \'long\'\n  };\n  let offOpts = {\n    hour: \'numeric\',\n    hour12: false,\n    timeZone: repLoc,\n    timeZoneName: \'short\'\n  }\n  if (repLoc == \'default\') {\n    el0.textContent = \'\';\n    el1.textContent = \'\';\n    el2.textContent = \'\';\n    el3.textContent = \'\';\n  } else {\n    el0.textContent = d0.toLocaleString(\'en-NZ\', opts);\n    el1.textContent = d0.toLocaleString(\'en-NZ\', offOpts).split(\' \')[1];\n    el2.textContent = d1.toLocaleString(\'en-NZ\', opts);\n    el3.textContent = d1.toLocaleString(\'en-NZ\', offOpts).split(\' \')[1];\n  }\n}\n\nwindow.onload = function(){\n  let sel = document.getElementById(\'repLoc\')\n  if (repLoc) {\n    sel.options[0].text = repLoc;\n    sel.options[0].value = repLoc;\n    sel.selectedIndex = 0;\n    setRepLoc.call(sel);\n  }\n  sel.addEventListener(\n    \'change\',\n    setRepLoc,\n    false);\n};
Run Code Online (Sandbox Code Playgroud)\r\n
td:nth-child(1){text-align:right;color:#999;}\ntd:nth-child(2){font-family:monospace}
Run Code Online (Sandbox Code Playgroud)\r\n
<table>\n  <tr>\n    <td>IANA loc:\n    <td><select id="repLoc">\n          <option selected value="default">Select a location\n          <option>Europe/Amsterdam\n          <option>Europe/Andorra\n          <option>Europe/Astrakhan\n          <option>Europe/Athens\n          <option>Europe/Belfast\n          <option>Pacific/Samoa\n          <option>Pacific/Kiritimati\n          <option>Antarctica/DumontDUrville\n          <option>Antarctica/Davis\n          <option>America/Chicago\n          <option>Australia/Brisbane\n        </select>\n  <tr>\n    <td>Sample:\n    <td id="sDate0">\n  <tr>\n    <td>Offset:\n    <td id="sOff0">\n  <tr>\n    <td>Sample:\n    <td id="sDate1">\n  <tr>\n    <td>Offset:\n    <td id="sOff1">\n\n</table>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n