在Javascript中从时区获取utc偏移量

时间:2013-12-20 21:45:32

标签: javascript timezone datejs

我需要一个给出时区的Javascript函数,返回当前的utc偏移量。

例如,theFuncIneed('US / Eastern') - > 240

有什么想法吗?

由于

5 个答案:

答案 0 :(得分:4)

一般情况下,这是不可能的。

  • US/Eastern时区的标识符。 (它实际上是America/New_York的别名,这是真正的标识符。)

  • 240是时区 offset 。它通常写成-04:00(反转符号,除以60)。

  • 美国东部时区由东部标准时间组成,其偏移量为-05:00和东部夏令时,其偏移量为-04:00

    < / LI>

所以说US/Eastern = 240并不准确。请阅读timezone tag wiki,特别是标题为“时区!=偏移”的部分。

现在你确实要求当前偏移, 可能。如果您提供日期+时间参考,则可以解决此问题。

  • 对于执行javascript代码的计算机的本地时区,这是使用来自.getTimeZoneOffset()对象的任何实例的Date内置的。

  • 但如果您希望将其用于特定的时区,则需要使用one of the libraries I listed here

答案 1 :(得分:3)

以下功能可用于返回给定时区的UTC偏移量:

[[15, 14, 15, 17, 17], [18, 17]]

它可以像这样使用:

const getTimezoneOffset = (timeZone, date = new Date()) => {
  const tz = date.toLocaleString("en", {timeZone, timeStyle: "long"}).split(" ").slice(-1)[0];
  const dateString = date.toString();
  const offset = Date.parse(`${dateString} UTC`) - Date.parse(`${dateString} ${tz}`);
  
  // return UTC offset in millis
  return offset;
}

答案 2 :(得分:1)

您可以使用moment.js

执行此操作
  

moment.tz('timezone name')。utcOffset()

虽然这涉及使用moment-timezone.js

答案 3 :(得分:0)

如今Intl API成为可能:

Intl的实现基于icu4c。如果您查看源代码,则会发现时区名称因地区而异,例如:

for (const locale of ["ja", "en", "fr"]) {
  const timeZoneName = Intl.DateTimeFormat(locale, {
    timeZoneName: "short",
    timeZone: "Asia/Tokyo",
  })
    .formatToParts()
    .find((i) => i.type === "timeZoneName").value;
  console.log(timeZoneName);
}

幸运的是,有一个语言环境Interlingua(语言标记为ia),其时区名称使用相同的模式(例如GMT+11:00)。

下面的代码片段可以满足您的需求:

const getOffset = (timeZone) => {
  const timeZoneName = Intl.DateTimeFormat("ia", {
    timeZoneName: "short",
    timeZone,
  })
    .formatToParts()
    .find((i) => i.type === "timeZoneName").value;
  const offset = timeZoneName.slice(3);
  if (!offset) return 0;

  const matchData = offset.match(/([+-])(\d+)(?::(\d+))?/);
  if (!matchData) throw `cannot parse timezone name: ${timeZoneName}`;

  const [, sign, hour, minute] = matchData;
  let result = parseInt(hour) * 60;
  if (sign === "+") result *= -1;
  if (minute) result += parseInt(minute);

  return result;
};

console.log(getOffset("US/Eastern"));
console.log(getOffset("Atlantic/Reykjavik"));
console.log(getOffset("Asia/Tokyo"));

这种方法可能有点棘手,但在我的生产项目中效果很好。我希望它也对您有帮助:)

更新

非常感谢Bort指出了错字。我已经纠正了代码段。

答案 4 :(得分:0)

@ranjan_purbey 的回答对我来说是 NaN,@Weihang Jian 的回答在 Chrome 中引发异常(但在 Firefox 中有效)。

因此,基于所有的答案,我想出了以下功能,它基本上是两个答案的组合,对我来说成功了:

const getTimeZoneOffset(timeZone) {
    const date = new Date().toLocaleString('en', {timeZone, timeZoneName: 'short'}).split(' ');
    const timeZoneName = date[date.length - 1];
    const offset = timeZoneName.slice(3);
    if (!offset) {
      return 0;
    }
    const matchData = offset.match(/([+-])(\d+)(?::(\d+))?/);
    if (!matchData) {
      throw new Error(`Cannot parse timezone name: ${timeZoneName}`);
    }
    const [, sign, hour, minute] = matchData;
    let result = parseInt(hour, 10) * 60;
    if (sign === '+') {
      result *= -1;
    }
    if (minute) {
      result += parseInt(minute, 10);
    }
    return result;
}