【发布时间】:2011-10-19 20:40:01
【问题描述】:
【问题讨论】:
-
我写了上面链接的 jsTimezoneDetect,我对这种情况的看法是,它与纯跨浏览器 javascript(没有地理定位和 IP 查找)尽可能接近。
标签: javascript http browser timezone
【问题讨论】:
标签: javascript http browser timezone
五年后,我们有了一个内置的方法! 对于现代浏览器,我会使用:
const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
console.log(tz);
这将返回 IANA 时区字符串,但不返回 the offset。通过MDN reference了解更多信息。
Compatibility table - 截至 2019 年 3 月,适用于全球 90% 的浏览器。 Doesn't work on Internet Explorer.
【讨论】:
Intl.DateTimeFormat().resolvedOptions().timeZone 将从 Firefox 52 开始返回预期值:kangax.github.io/compat-table/esintl/…
看看这个仓库pageloom很有帮助
下载 jstz.min.js 并在你的 html 页面中添加一个函数
<script language="javascript">
function getTimezoneName() {
timezone = jstz.determine()
return timezone.name();
}
</script>
并从您的显示标签调用此函数
【讨论】:
Intl.DateTimeFormat().resolvedOptions().timeZone(无 IE11)。
通常当人们在寻找“时区”时,“UTC 偏移量”就足够了。 例如,他们的服务器在 UTC+5 中,他们想知道他们的客户端在 UTC-8 中运行。
在普通的旧 javascript 中,(new Date()).getTimezoneOffset()/60 将返回与 UTC 偏移的当前小时数。
值得注意的是,getTimezoneOffset() 返回值 (from MDN docs) 的符号中可能存在“陷阱”:
时区偏移是 UTC 和本地时间之间的差异,以分钟为单位。请注意,这意味着如果本地时区晚于 UTC,则偏移量为正,如果早于 UTC,则偏移量为负。例如,对于时区 UTC+10:00(澳大利亚东部标准时间、符拉迪沃斯托克时间、查莫罗标准时间),将返回 -600。
但是,我建议您将day.js 用于与时间/日期相关的 Javascript 代码。在这种情况下,您可以通过运行获得 ISO 8601 格式的 UTC 偏移量:
> dayjs().format("Z")
"-08:00"
值得一提的是,客户很容易伪造这些信息。
(注意:这个答案最初推荐https://momentjs.com/,但dayjs 是一个更现代、更小的替代方案。)
【讨论】:
目前,最好的选择可能是 mbayloon's answer 中建议的 jstz。
为了完整起见,应该提到它有一个标准:Intl。您已经可以在 Chrome 中看到这一点:
> Intl.DateTimeFormat().resolvedOptions().timeZone
"America/Los_Angeles"
(这实际上并不遵循标准,这是坚持使用该库的另一个原因)
【讨论】:
Intl 的实现应该为timeZone 属性返回undefined @。 Chrome 通过返回系统的时区来偏离标准;这就是约翰内斯的回答所利用的,也是他说“实际上并不遵循标准”的原因。
您可以使用moment-timezone 来猜测时区:
> moment.tz.guess()
"America/Asuncion"
【讨论】:
这是jsfiddle
它提供了当前用户时区的缩写。
这里是代码示例
var tz = jstz.determine();
console.log(tz.name());
console.log(moment.tz.zone(tz.name()).abbr(new Date().getTime()));
【讨论】:
May 22 2015 03:45 PM CDT 我使用了console.log(moment(now).format('MMM DD YYYY hh:mm A') + ' ' + moment.tz.zone(tz.name()).abbr(now.getTime()));
我使用了类似于the one taken by Josh Fraser 的方法,它确定了浏览器与UTC 的时间偏移量以及它是否识别DST(但从他的代码中有所简化):
var ClientTZ = {
UTCoffset: 0, // Browser time offset from UTC in minutes
UTCoffsetT: '+0000S', // Browser time offset from UTC in '±hhmmD' form
hasDST: false, // Browser time observes DST
// Determine browser's timezone and DST
getBrowserTZ: function () {
var self = ClientTZ;
// Determine UTC time offset
var now = new Date();
var date1 = new Date(now.getFullYear(), 1-1, 1, 0, 0, 0, 0); // Jan
var diff1 = -date1.getTimezoneOffset();
self.UTCoffset = diff1;
// Determine DST use
var date2 = new Date(now.getFullYear(), 6-1, 1, 0, 0, 0, 0); // Jun
var diff2 = -date2.getTimezoneOffset();
if (diff1 != diff2) {
self.hasDST = true;
if (diff1 - diff2 >= 0)
self.UTCoffset = diff2; // East of GMT
}
// Convert UTC offset to ±hhmmD form
diff2 = (diff1 < 0 ? -diff1 : diff1) / 60;
var hr = Math.floor(diff2);
var min = diff2 - hr;
diff2 = hr * 100 + min * 60;
self.UTCoffsetT = (diff1 < 0 ? '-' : '+') + (hr < 10 ? '0' : '') + diff2.toString() + (self.hasDST ? 'D' : 'S');
return self.UTCoffset;
}
};
// Onload
ClientTZ.getBrowserTZ();
加载后,ClientTZ.getBrowserTZ() 函数被执行,它设置:
ClientTZ.UTCoffset 到浏览器与 UTC 的时间偏移,以分钟为单位(例如,CST 为 -360 分钟,与 UTC 相差 -6.0 小时);ClientTZ.UTCoffsetT 到 '±hhmmD' 形式的偏移量(例如,'-0600D'),其中后缀为 D 用于 DST,S 用于标准(非 DST);ClientTZ.hasDST(对或错)。ClientTZ.UTCoffset 以分钟而不是小时提供,因为某些时区具有小数小时偏移量(例如,+0415)。
ClientTZ.UTCoffsetT 背后的意图是将其用作时区表(此处未提供)的键,例如用于下拉 <select> 列表。
【讨论】:
7-1。我不确定这是否真的有什么不同,因为我怀疑是否存在不包括 6 月的区域 DST 计划。
没有。没有单一可靠的方法,而且永远不会有。你真的认为你可以信任客户吗?
【讨论】: