【问题标题】:How to get the canonical timezone name of a timezone alias?如何获取时区别名的规范时区名称?
【发布时间】:2021-11-28 01:47:25
【问题描述】:

我想创建一个函数,将时区别名转换为所述时区的规范名称。

Status of timezones from Wikipedia

例如,如果我有 Africa/Accra,我希望能够查找 Africa/Abidjan 是时区的规范名称。

function getCanonicalName(name) {
  // TODO
}
getCanonicalName('Africa/Accra'); // => 'Africa/Abidjan'

我自己调查过的事情

我曾尝试使用moment-timezoneluxon 来解析区域名称,但似乎没有办法将规范时区作为这些库的一部分进行逆向工程。

根据moment-timezone docs,您可以从“打包”数据表示中获取时区的规范名称,但在其源代码中looking at the implementation of pack,似乎只是通过source.name

luxon 有一个 normalizeZone 帮助器,但这似乎只是从各种输入类型返回一个 Zone 实例。但是,它不会规范化区域名称。 luxon Zones 上有一个isUniversal 标志,但是这个标志似乎与夏令时有关,而不是时区的状态。

【问题讨论】:

  • 现在有guess() API吗? Link to Docs
  • 谢谢,guess() API 足以获取当前用户的时区,但我们的服务还需要向管理员显示存储在用户记录中的用户时区信息。我们允许他们存储时区别名,但我们希望将它们标准化为规范时区,所以我认为 guess 是不够的。

标签: javascript timezone moment-timezone luxon


【解决方案1】:

这可能无法将该特定区域识别为别名,因为它已在 September 2021 中更新:

但总的来说:

import moment from 'moment';
import momenttz from 'moment-timezone';

// From moment-timezone, but not exported
function normalizeName (name) {
  return (name || '').toLowerCase().replace(/\//g, '_');
}

function getCanonicalName(name) {
  const normalizedName = normalizeName(name);

  // A canonical zone might exist
  if (moment.tz._zones[normalizedName]) {
    return moment.tz._names[normalizedName];
  }

  // If not, there'll be a link to a canonical name
  const canonicalZoneNormalized = moment.tz._links[normalizeName(name)];

  // And return the friendly name
  return moment.tz._names[canonicalZoneNormalized];
}

console.log(getCanonicalName('Pacific/Wallis')); // => Pacific/Tarawa
console.log(getCanonicalName('Pacific/Tarawa')); // => Pacific/Tarawa

【讨论】:

    【解决方案2】:

    鉴于时区数据库每年只更新一次,我认为我的解决方案是低维护。我在这里遵循一种非常粗略的方法。实际上,您可以先将 wikipedia 页面上显示的信息转换为 JSON,然后通过在浏览器控制台中运行它来获取包含所有时区及其规范时区的地图:

    const keys = [];
    const timezones = [];
    
    $("table:first thead tr th").each(function () {
        keys.push($(this).text().replace(/\n/g, ''));
    });
    
    $("table:first tbody tr").each(function () {
        const obj = {};
        let i = 0;
    
        $(this).children("td").each(function () {
            obj[keys[i]] = $(this).text().replace(/\n/g, '');
            i++;
        });
    
        timezones.push(obj);
    });
    
    const canonicalTimezones = Object.assign({}, ...timezones.map(x => ({ [x['TZ database name']]: (x['Type'] === 'Canonical' ? x['TZ database name'] : x['Notes'].substring(8)) })));
    
    JSON.stringify(canonicalTimezones);
    

    您可以将输出保存在某个文件中。然后您只需要在代码中解析它并轻松获取相应的规范时区。

    import canonicalTimezones from './canonicalTimezones.json';
    
    function getCanonicalName(name) {
      return canonicalTimezones[name];
    }
    

    【讨论】:

      猜你喜欢
      • 2012-09-13
      • 2013-08-17
      • 2013-03-03
      • 2021-04-11
      • 1970-01-01
      • 1970-01-01
      • 2012-04-04
      • 1970-01-01
      • 2015-09-29
      相关资源
      最近更新 更多