如何获取时区别名的规范时区名称?

4
我希望创建一个函数,将时区别名转换为所述时区的规范名称。 维基百科上的时区状态 例如,如果我有“Africa/Accra”,我希望能够查找“Africa/Abidjan”是该时区的规范名称。
function getCanonicalName(name) {
  // TODO
}
getCanonicalName('Africa/Accra'); // => 'Africa/Abidjan'

我自己调查过的事情

我尝试使用 moment-timezoneluxon 来解析时区名称,但这些库似乎没有一种方法可以反向工程出规范时区。

根据 moment-timezone 文档,您可以从“打包”数据表示中获取时区的规范名称,但是 查看他们源代码中pack的实现,它似乎只是通过 source.name 传递。

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


现在moment有guess() API了吗? 文档链接 - Vishnu
谢谢,guess() API足以获取当前用户的时区,但我们的服务还需要展示管理员存储在用户记录上的用户时区信息。我们允许他们存储时区别名,但我们希望将它们规范化为规范时区,因此我认为guess不足够。 - Souperman
2个回答

3

由于该区域已在2021年9月进行更新,因此可能无法将其识别为别名:

但通常情况如下:

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

0
鉴于时区数据库仅一年更新一次,我认为我的解决方案很低维护。这里我遵循了非常粗略的方法。你实际上可以先将维基百科页面上显示的信息转换成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];
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接