首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用户友好时区名称对应于IANA名称

用户友好时区名称对应于IANA名称
EN

Stack Overflow用户
提问于 2020-04-13 10:58:20
回答 3查看 3.2K关注 0票数 6

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

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

它还将删除用户认为是“相同”时区的列表。例如,Pacific time (美国和加拿大)的列表将对应于美国/洛杉矶和美国/蒂华纳,它们是“相同的”时间。

我试过查看IANA时区数据库ECMA脚本国际化APIMoment.js这样的库。它们可以将IANA名称解析为公共名称,例如America/Los_Angeles ==> "Pacific Standard Time",但是没有一个内置函数来列出所有公共名称及其对应的IANA名称。

EN

回答 3

Stack Overflow用户

发布于 2020-04-13 23:19:41

简单的回答是,从IANA代表的位置名称到通用名称没有简单的地图,因为IANA名称没有反映偏移量或夏时制方面的历史变化,也没有正式或事实上充分标准化通用名称。

长答案

IANA具有代表性的地点包括时区偏移的历史性变化,包括当地时间和夏令,因为这些年来一直在使用。标准时区名称可能没有更改,但是偏移已经并将继续更改。另外,IANA代表的位置名称在夏令期间保持不变,但是偏移量和普通名称不一样。

例如,萨摩亚的IANA名称为“Pacific/萨摩亚”。它在2011年12月29日之前的标准偏移量是UTC−11:00,但之后它的偏移量是UTC+13:00,它的夏令时从UTC-1000转到了UTC+14:00。时区的常用名称是“萨摩亚标准时间”和“萨摩亚夏时制”,但这些名称没有标准化,而且在许多地方含糊不清(例如,CST可能是2或3个不同地点的中央标准时间,或中国标准时间)。

因此,从IANA代表的位置名称到所有IANA位置的公共时区名称没有简单的地图。您可能可以为一个小的子集创建一个,但是使用内置的Intl对象可能更简单。

代码语言:javascript
复制
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);

备注

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

您可以如下所示使用Intl对象,请注意,对于某些位置,它可能没有时区的名称,因此只显示偏移量(例如,try Europe/Astrakhan)。有近600个IANA地点。

代码语言:javascript
复制
// 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);
};
代码语言:javascript
复制
td:nth-child(1){text-align:right;color:#999;}
td:nth-child(2){font-family:monospace}
代码语言:javascript
复制
<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>

票数 3
EN

Stack Overflow用户

发布于 2021-09-07 08:16:29

您可以使用Intl.DateTimeFormat.prototype.formatToParts()

代码语言:javascript
复制
new Intl.DateTimeFormat(
    'default',
    { timeZone: 'America/Los_Angeles', timeZoneName: 'long' }
).formatToParts().find(({ type }) => type === 'timeZoneName').value
// 'Pacific Daylight Time'
票数 3
EN

Stack Overflow用户

发布于 2022-02-11 23:11:41

在Kimamula回答的基础上,我获取了IANA时区名称的当前列表,并在浏览器的Intl格式化程序中运行它,以获得所有时区名称的长和短名称。结果是一个带有IANA名称到人类可读的名称的映射的要点。我采用了这些名字的“通用”形式,没有提到夏令时。否则,我们需要知道DST是否有效来选择名称。(例如太平洋时间而不是太平洋标准时间或太平洋夏时制)。

不是每个时区在这个数据库中都有一个理想的名称,因为大多数与时间相关的东西,这将是一个不完美的解决方案。但它有望涵盖最受用户欢迎的时区,显示IANA名称作为后盾是一种选择。

如果您想自己生成这些名称,您可以在浏览器中运行这些名称。这些名称来自Firefox,我猜想它们与实现有关,在其他浏览器中可能有些不同。

代码语言:javascript
复制
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
   }

})
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61186388

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档