24

I need a Javascript function that given a timezone, returns the current utc offset.

For example, theFuncIneed('US/Eastern') -> 240

Any idea?

Thanks

4

5 回答 5

9

一般来说,这是不可能的。

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

  • 240是时区偏移量。它更常见地写为-04:00 (反转符号,除以 60)。

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

所以说US/Eastern= 240 一点也不准确。请阅读时区标签 wiki,尤其是标题为“时区!=偏移”的部分。

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

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

  • 但是,如果您希望它用于特定时区,那么您将需要使用我在此处列出的库之一

于 2013-12-20T22:33:05.090 回答
5

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

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;
}

它可以像这样使用:

const offset = getTimezoneOffset("Europe/London");
console.log(offset);
// expected output => 3600000
于 2020-07-31T21:49:08.753 回答
2

现在使用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")); // 240
console.log(getOffset("Atlantic/Reykjavik")); // 0
console.log(getOffset("Asia/Tokyo")); // -540

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

更新

非常感谢 Bort 指出错字。我已经更正了片段。

于 2020-10-08T12:45:34.990 回答
1

You can do this using moment.js

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

Although this involves using moment-timezone.js

于 2015-08-12T18:00:40.700 回答
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;
}
于 2021-07-07T09:44:14.663 回答