20

我正在寻找的是一种检测浏览器时区 ID(如Olson 表中定义)的方法,但我不关心确切的 ID,我只需要与用户的时区相同的时区 ID (例如,如果用户在巴黎,“欧洲/罗马”就可以了)。

我对当前的偏移量不感兴趣,我真的需要时区,以便我可以将它发送到服务器以计算其他日期(服务器也有 Olson 表)。

从理论上讲,由于我已经使用了 Moment.js 时区库并包含了 Olson 表,因此我不需要其他任何东西,但我没有找到任何 API 来进行检测。我不知道它是否隐藏在某个地方,或者是否有人已经写了它。问题之一是当前时区插件似乎将其数据保密。

想要一个基于 Olson 表的另一个副本或提取(我必须维护)的集成的解决方案,我知道有一些库复制它们,我想使用我已经在 Moment 中拥有的那些.js。

4

4 回答 4

17

我制作了一个小脚本来进行检测。它首先注册可用时区的 ID,然后在调用该matches函数时测试当前时间的所有时区 ID,以及 4 个月和 8 个月后(以过滤出具有不同日光规则的时区)和五年前的时间.

这里是 :

<script src="moment-with-langs.min.js"></script>
<script src="moment-timezone.min.js"></script>
<script src="moment-timezone-data.js"></script>
<script>
var tzdetect = {
    names: moment.tz.names(),
    matches: function(base){
        var results = [], now = Date.now(), makekey = function(id){
            return [0, 4, 8, -5*12, 4-5*12, 8-5*12, 4-2*12, 8-2*12].map(function(months){
                var m = moment(now + months*30*24*60*60*1000);
                if (id) m.tz(id);
                return m.format("DDHHmm");
            }).join(' ');
        }, lockey = makekey(base);
        tzdetect.names.forEach(function(id){
            if (makekey(id)===lockey) results.push(id);
        });
        return results;
    }
};
</script>

如果您只想要一个时区 ID,只需使用

var tzid = tzdetect.matches()[0];

示范

GitHub 存储库:https ://github.com/Canop/tzdetect.js

更新:此处显示的代码与最新版本的 moment.js 不兼容。请参阅GitHub 存储库以获取维护(免费使用)的代码。

2017 年更新: moment.js 中现在有一个 API 来猜测时区。这可能是目前最好的解决方案。

于 2013-10-17T08:27:40.300 回答
11

如果你想使用标准的 JavaScript API,你可以Intl.DateTimeFormat.resolvedOptions在有浏览器支持的地方使用:

Intl.DateTimeFormat().resolvedOptions().timeZone; // "America/Los_Angeles"

resolvedOptions目前(2016 年 1 月)可在除 iOS 和桌面上的 Safari 之外的所有浏览器中使用:http: //caniuse.com/#feat=internationalization

但是,该timeZone属性目前仅在 Chrome 上可用

于 2013-10-17T08:55:53.960 回答
7

现在有这里描述guess()的API

于 2016-04-12T18:13:04.620 回答
-1

有一个 javascript 工具可以做到这一点:

https://github.com/entraigas/jstz

它似乎也处理时区的歧义。

结合momentJS时区,可以获取时区并显示格式化日期:

var tzObj = jstz.determine();
var timezoneCode = tzObj.name();
console.log(moment.tz(timeZoneCode).format());
于 2014-10-06T16:15:35.087 回答