协慌网

登录 贡献 社区

在 JavaScript 中获取客户端的时区(和偏移量)

如何收集访客的时区信息?

我都需要:

  1. 时区(例如,欧洲 / 伦敦)
  2. 以及与 UTC 或 GMT 的偏移量(例如 UTC + 01)

答案

使用偏移量来计算时区是错误的方法,并且您总是会遇到问题。一年中的时区和夏令时规则可能会多次更改,因此很难跟上这些更改。

要使用 JavaScript 获取系统的IANA 时区,您应该使用

console.log(Intl.DateTimeFormat().resolvedOptions().timeZone)

截至 2019 年 9 月,此方法可在全球 95%的浏览器中使用

旧的兼容性信息

ecma-402 / 1.0 表示, timeZone提供给构造函数,则可能未定义。但是,将来的草案(3.0)通过更改为系统默认时区来解决该问题。

在这个版本中的 ECMAScript 国际化 API 中, timeZone如果没有属性将仍然不确定timeZone属性是在选项提供的对象提供给Intl.DateTimeFormat构造。但是,应用程序不应依赖于此,因为将来的版本可能会返回一个 String 值,该值标识主机环境的当前时区。

在仍处于草案中的 ecma-402 / 3.0 中,将其更改为

在这个版本的 ECMAScript 的 2015 年国际化 API 中, timeZone属性将是,如果没有默认的时区的名称timeZone属性是在选项提供的对象提供给Intl.DateTimeFormat构造。在这种情况下,先前的版本timeZone

使用getTimezoneOffset()

您可以像这样以分钟为单位获取时区偏移量:

var offset = new Date().getTimezoneOffset();
console.log(offset);
// if offset equals -60 then the time zone offset is UTC+01

时区偏移量是 UTC 与本地时间之间的差(以分钟为单位)。请注意,这意味着如果本地时区在 UTC 之后,则偏移量为正,如果在时区之前,则偏移量为负。例如,如果您的时区是 UTC + 10(澳大利亚东部标准时间),则将返回 - 600。夏时制即使在给定的语言环境下,也无法使该值保持恒定

请注意,并非所有时区都被整个小时抵消:例如,纽芬兰是 UTC 减去 3h 30m(将夏令时排除在外)。

另请注意,这仅为您提供时区偏移(例如:UTC + 01),而没有给您时区(例如:欧洲 / 伦敦)。

我意识到这个答案有点离题,但我想我们当中许多人都在寻找答案,但他们也想格式化显示的时区,也许还要获得时区的缩写。所以就这样...

如果您希望客户端时区的格式正确,则可以依靠 JavaScript Date.toString 方法并执行以下操作:

var split = new Date().toString().split(" ");
var timeZoneFormatted = split[split.length - 2] + " " + split[split.length - 1];

例如,这将为您提供 “GMT-0400(EST)”,包括时区分钟(如果适用)。

另外,使用正则表达式,您可以提取任何所需的部分:

对于 “GMT-0400(EDT)”:

new Date().toString().match(/([A-Z]+[\+-][0-9]+.*)/)[1]

对于 “GMT-0400”:

new Date().toString().match(/([A-Z]+[\+-][0-9]+)/)[1]

仅针对 “EDT”:

new Date().toString().match(/\(([A-Za-z\s].*)\)/)[1]

对于 “-0400”:

new Date().toString().match(/([-\+][0-9]+)\s/)[1]

Date.toString 参考: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/toString

编辑 10/6/2020 - 上面的解决方案可能不适用于所有浏览器和语言环境。我目前的建议是利用图书馆。一些不错的流行库是:moment,date-fns 2,luxon 或 dayjs。