从浏览器获取客户端时区

时间:2011-08-04 10:19:59

标签: javascript http browser timezone

是否有可靠的方法从客户端浏览器获取时区?我看到了以下链接,但我想要一个更强大的解决方案。

Auto detect a time zone with JavaScript

Timezone detection in JavaScript

9 个答案:

答案 0 :(得分:113)

五年后,我们有了内置的方式! 对于现代浏览器,我会使用:



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

答案 1 :(得分:78)

查看此存储库pageloom这是有帮助的

下载jstz.min.js并将功能添加到您的html页面

<script language="javascript">
    function getTimezoneName() {
        timezone = jstz.determine()
        return timezone.name();
    }
</script>

并从显示标记

调用此函数

答案 2 :(得分:64)

通常当人们在寻找“时区”时,只需“UTC偏移”即可。例如,他们的服务器是UTC + 5,他们想知道他们的客户端是在UTC-8 中运行。


在普通旧版本中,javascript (new Date()).getTimezoneOffset()/60将返回当前偏离UTC的小时数。

值得注意的是getTimezoneOffset()返回值(from MDN docs)的符号中可能出现的“陷阱”:

  

时区偏移是UTC与本地时间之间的差异(以分钟为单位)。请注意,这意味着如果本地时区落后于UTC,则偏移量为正,如果前置,则偏移量为负。例如,对于时区UTC + 10:00(澳大利亚东部标准时间,符拉迪沃斯托克时间,查莫罗标准时间),将返回-600。


但是,我建议您使用day.js与时间/日期相关的Javascript代码。在这种情况下,您可以通过运行以下方式获得ISO 8601格式的UTC偏移:

> dayjs().format("Z")
"-08:00"

可能有人提到客户可以轻易伪造这些信息。

(注意:这个答案最初推荐https://momentjs.com/,但是dayjs是一个更现代,更小的选择。)

答案 3 :(得分:41)

目前,最好的选择可能是mbayloon's answer中建议的jstz。

为了完整起见,应该提到它有一个标准:Intl。您可以在Chrome中看到此内容:

> Intl.DateTimeFormat().resolved.timeZone
"America/Los_Angeles"

(这实际上并不遵循标准,这是坚持使用该库的另一个原因)

答案 4 :(得分:5)

这是jsfiddle

它提供当前用户时区的缩写。

以下是代码示例

var tz = jstz.determine();
console.log(tz.name());
console.log(moment.tz.zone(tz.name()).abbr(new Date().getTime()));

答案 5 :(得分:2)

我使用了一种类似于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'),其中DST的后缀为D,标准后缀为S -dst);
  • ClientTZ.hasDST(判断为真或假)。

ClientTZ.UTCoffset以分钟而非数小时的形式提供,因为某些时区有小时偏差(例如,+ 0415)。

ClientTZ.UTCoffsetT背后的意图是将其用作时区表(此处未提供)的键,例如下拉<select>列表。

答案 6 :(得分:2)

您可以使用moment-timezone来猜测时区:

> moment.tz.guess()
"America/Asuncion"

答案 7 :(得分:2)

以下是使用fetch和https://worldtimeapi.org/api

的版本,在2020年9月运行良好

fetch("https://worldtimeapi.org/api/ip")
  .then(response => response.json())
  .then(data => console.log(data.timezone,data.datetime,data.dst));

答案 8 :(得分:-10)

没有。没有一种可靠的方法,永远不会有。你真的认为你可以信任客户吗?