如何收集访问者的时区信息?
我需要两个:
- 时区(例如,欧洲/伦敦)
- 以及与 UTC 或 GMT 的偏移量(例如,UTC+01)
如何收集访问者的时区信息?
我需要两个:
使用偏移量来计算时区是一种错误的方法,你总会遇到问题。时区和夏令时规则在一年中可能会多次更改,并且很难跟上变化。
要在 JavaScript 中获取系统的IANA 时区,您应该使用
console.log(Intl.DateTimeFormat().resolvedOptions().timeZone)
ecma-402/1.0 表示timeZone
如果未提供给构造函数,则可能未定义。但是,未来的草案 (3.0) 通过更改为系统默认时区来解决该问题。
在此版本的 ECMAScript 国际化 API 中,
timeZone
如果timeZone
提供给Intl.DateTimeFormat
构造函数的选项对象中未提供任何属性,则该 属性将保持未定义状态。但是,应用程序不应依赖于此,因为未来的版本可能会返回一个字符串值来标识主机环境的当前时区。
在仍处于草案中的 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 减去 3 小时 30 米(将夏令时排除在等式之外)。
另请注意,这只会为您提供时区偏移量(例如: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 - 上述解决方案可能不适用于所有浏览器和语言环境。如果在您的场景中可能,我建议您使用提供时区支持的 javascript 库,如 date-fns、luxon 或 dayjs。
已经回答了如何以整数形式在分钟内获得偏移量,但如果有人想要本地 GMT 偏移量作为字符串,例如"+1130"
:
function pad(number, length){
var str = "" + number
while (str.length < length) {
str = '0'+str
}
return str
}
var offset = new Date().getTimezoneOffset()
offset = ((offset<0? '+':'-')+ // Note the reversed sign!
pad(parseInt(Math.abs(offset/60)), 2)+
pad(Math.abs(offset%60), 2))
您可以使用:
<script src="moment.js"></script>
<script src="moment-timezone-with-data.js"></script>
// retrieve timezone by name (i.e. "America/Chicago")
moment.tz.guess();
浏览器时区检测很难做到正确,因为浏览器提供的信息很少。
Moment Timezone 使用Date.getTimezoneOffset()
和Date.toString()
在当年的少数时刻来收集尽可能多的关于浏览器环境的信息。然后将该信息与加载的所有时区数据进行比较,并返回最接近的匹配项。如果有关系,则返回人口最多的城市所在的时区。
console.log(moment.tz.guess()); // America/Chicago