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

Árv*_*gép 569 javascript timezone

我如何收集访客的时区信息?我需要Timezone,以及GMT抵消时间.

Nic*_*itz 549

var offset = new Date().getTimezoneOffset();
console.log(offset);
Run Code Online (Sandbox Code Playgroud)

时区偏移是UTC与本地时间之间的差异(以分钟为单位).请注意,这意味着如果本地时区落后于UTC,则偏移量为正,如果前置,则偏移量为负.例如,如果您的时区是UTC + 10(澳大利亚东部标准时间),则将返回-600.夏令时可以防止该值即使对于给定的区域设置也是常量

请注意,并非所有时区都按整个小时偏移:例如,纽芬兰是UTC减去3小时30分钟(将夏令时排除在等式之外).

  • `var hrs = - (new Date().getTimezoneOffset()/ 60)`以获得通常使用的小时偏移 (43认同)
  • @abernier关于`getTimezoneOffset`不准确的陈述是否有效?您所指的文章的日期为2007年6月,并且没有详细说明该函数的不准确性.实际上你指向的库`jsTimezoneDetect`本身使用`getTimezoneOffset`. (42认同)
  • `timezone`!=`utc offset` (12认同)
  • 似乎它不考虑夏令时 (6认同)
  • @abernier这是自ES 1以来的一个标准,所以我确定现在可以修复任何实现问题,我的意思是,这是一篇7年前的文章. (5认同)
  • Intl.DateTimeFormat().resolvedOptions().timeZone将给出cient的时区. (3认同)
  • 使用'Date.getTimezoneOffset()'函数一切都很好,但是为了确定正确的时区名称,仅基于偏移量,您可能需要'jsTimezoneDetect'库. (2认同)
  • @Shahdat它为我考虑了夏令时。 (2认同)
  • @MohammedShareefC 仔细阅读文档,UTC 和本地时间之间的差异。UTC = 12:00,本地 = 12:00 + 5:30 = 17:30,所以差为 12:00 - 17:30 = -5:30 (2认同)
  • var hrs = new Date().getTimezoneOffset() / -60; // 少括号 (2认同)

Paw*_*iel 390

使用偏移量来计算时区是一种错误的方法,您将始终遇到问题.时区和夏令时规则可能会在一年内多次改变,并且很难跟上变化.

要在JavaScript中获得正确的时区,您应该使用

console.log(Intl.DateTimeFormat().resolvedOptions().timeZone)
Run Code Online (Sandbox Code Playgroud)

不幸的是,到撰写本文时,它还没有被广泛支持.
我知道它至少在Chrome中正常运行.

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

在此版本的ECMAScript Internationalization API中,timeZone如果timeZone在提供给Intl.DateTimeFormat 构造函数的options对象中未提供任何属性,则该 属性将保持未定义.但是,应用程序不应该依赖于此,因为将来的版本可能会返回一个String值来标识主机环境的当前时区.

在ecma-402/3.0中,它仍然在草案中改为

在此版本的ECMAScript 2015 Internationalization API中,timeZone如果timeZone在提供给Intl.DateTimeFormat构造函数的options对象中未提供任何属性 ,则该 属性将是默认时区的名称 .timeZone在这种情况下,之前的版本使 属性未定义.

因此,在使用它之前,请检查浏览器的当前支持,例如:https:
//developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat/resolvedOptions

  • 这是获取时区的唯一答案,一些用户可能需要这个时区而不是偏移量.因此,作为2016-09的更新,Intl适用于大多数现代浏览器,但不适用于Safari.对于那个浏览器,这里有一个相当准确的javascript后备 - http://pellepim.bitbucket.org/jstz/ (14认同)
  • 我现在已经使用Chrome 58,Edge 40和Firefox 53进行了测试 - 它将全部运行.它不适用于IE 11,我没有测试Opera. (7认同)
  • 验证这现在似乎可以在Safari中使用.(使用10.0版) (5认同)
  • 我花了一些时间才能找到此API返回的时区列表。它在这里:https://en.wikipedia.org/wiki/List_of_tz_database_time_zones (4认同)
  • 如果这适用于所有现代浏览器,那将会很好.但是,IE11和最新的Firefox都为timeZone属性返回undefined. (2认同)
  • [`moment.js`](/sf/answers/2830472151/)使[use](https://momentjs.com/timezone/docs/#/using-timezones/guessing-user-timezone /)支持的地方。否则退回到`getTimezoneOffset()`。 (2认同)
  • 在 Edge 中,它返回“Asia/Kolkata”,而在 Chrome 中,它返回“Asia/Calcutta”代表印度。在服务器端导致我在 UTC 中转换的问题 (2认同)
  • @XavierPoinas 它可以从 `Intl` 对象 `Intl.supportedValuesOf('timeZone')` 访问!(然后你可以使用语言环境“ia”来获取偏移量) (2认同)

Mar*_*uez 120

我意识到这个答案有点偏离主题,但我想我们许多人在寻找答案时也希望格式化显示的时区,也许也会得到区域缩写.所以这里......

如果您希望客户端时区格式良好,您可以依赖JavaScript Date.toString方法并执行:

var split = new Date().toString().split(" ");
var timeZoneFormatted = split[split.length - 2] + " " + split[split.length - 1];
Run Code Online (Sandbox Code Playgroud)

例如,这将为您提供"GMT-0400(EST)",包括适用的时区分钟.

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

对于"GMT-0400(EDT)":

new Date().toString().match(/([A-Z]+[\+-][0-9]+.*)/)[1]
Run Code Online (Sandbox Code Playgroud)

对于"GMT-0400":

new Date().toString().match(/([A-Z]+[\+-][0-9]+)/)[1]
Run Code Online (Sandbox Code Playgroud)

对于"EDT":

new Date().toString().match(/\(([A-Za-z\s].*)\)/)[1]
Run Code Online (Sandbox Code Playgroud)

对于"-0400":

new Date().toString().match(/([-\+][0-9]+)\s/)[1]
Run Code Online (Sandbox Code Playgroud)

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

  • 在执行`new Date()之后,实际表示JS时间实际上并不是一个好主意.toString()`完全取决于您的语言环境设置.期待其他客户的产出与您的产品相似是一个非常糟糕的主意. (6认同)
  • 这也不适用于(惊喜,惊喜)IE.我只是做了拆分Date对象的控制台转储.在Chrome,Firefox和Safari中也是如此,但在IE中却有所不同.所以,你也不能指望不变的索引.2013年12月2日星期一10:22:50 GMT-0500(美国东部时间):Chrome,FF,Safari; 2013年12月2日星期一10:22:50:IE10 (4认同)
  • 在Chrome中添加了时区名称.不要使用split.length而是使用常量而不是`split [4] +""+ split [5]`! (3认同)
  • @adimauro ..现在在IE11工作;) (2认同)
  • 我结束了:`var fullTz = new Date().toString().match(/\(([A-Za-z\s].*)\)/)[1]; var 部分 = fullTz.split(' '); var tz = ""; part.forEach(function (element, index, array) { tz += element.substring(0, 1); });` 产生:“EST”,例如 (2认同)

cry*_*ryo 70

已经回答了如何以分钟为单位获得偏移量,但是如果有人希望将本地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))
Run Code Online (Sandbox Code Playgroud)


Sam*_* Ek 62

您可以使用:

那一刻,时区

<script src="moment.js"></script>
<script src="moment-timezone-with-data.js"></script>

// retrieve timezone by name (i.e. "America/Chicago")
moment.tz.guess();
Run Code Online (Sandbox Code Playgroud)

浏览器时区检测相当棘手,因为浏览器提供的信息很少.

那一刻时区使用Date.getTimezoneOffset(),并Date.toString()围绕本年度时刻屈指可数收集关于浏览器环境中尽可能多的信息.然后,它将该信息与加载的所有时区数据进行比较,并返回最接近的匹配.如果是关系,则返回人口最多的城市的时区.

console.log(moment.tz.guess()); // America/Chicago
Run Code Online (Sandbox Code Playgroud)

  • 这应该是公认的答案.这是唯一一个给出实际时区**名称**而不是偏移量的名称.请记住,时区偏移量可以从名称中导出,反之则不然.由于DST和其他细微之处,多个时区只能在一年中的某些特定日期具有相同的偏移量. (12认同)
  • 现在有一个本地解决方案 - [Intl API](/sf/answers/2625866001/)。虽然 moment.js 在当时是一个很棒的库,但目前还有更小的替代品 ([dayjs](https://github.com/iamkun/dayjs)、[date-fns](https://date-fns) .org/))。[瞬间是巨大的](https://github.com/moment/moment/issues/3376); 请不要将其推荐用于客户端应用程序。 (5认同)

Mr_*_*een 39

我在我的项目中编写了一个函数,它以hh:mm格式返回时区.我希望这可以帮助某人:

function getTimeZone() {
    var offset = new Date().getTimezoneOffset(), o = Math.abs(offset);
    return (offset < 0 ? "+" : "-") + ("00" + Math.floor(o / 60)).slice(-2) + ":" + ("00" + (o % 60)).slice(-2);
}
Run Code Online (Sandbox Code Playgroud)
// Outputs: +5:00
Run Code Online (Sandbox Code Playgroud)

function getTimeZone() {
  var offset = new Date().getTimezoneOffset(), o = Math.abs(offset);
  return (offset < 0 ? "+" : "-") + ("00" + Math.floor(o / 60)).slice(-2) + ":" + ("00" + (o % 60)).slice(-2);
}


// See output
document.write(getTimeZone());
Run Code Online (Sandbox Code Playgroud)

工作小提琴

  • 这返回时区偏移量(例如:UTC+01),它不返回时区(例如:欧洲/伦敦) (2认同)

Aid*_*din 17

这个问题已经有 30 多个答案,但我相信有些人会来到这里,但真的不知道他们在寻找什么。

\n

惊喜!你即将打开一罐蠕虫!

\n

我强烈建议阅读我最近写的这篇关于在 JS 中处理时区的令人头疼的文章!https://medium.com/@EyeDin/time-and-time-zone-headaches-in-javascript-ae4d873a665d

\n

您到底在寻找什么?

\n

根据您的实际用例,您实际上需要不同的东西。

\n
\n

1) 一种将固定时间点(例如旧金山 2021 年 11 月 13 日晚上 11:35:21)转换为用户的挂钟时间的方法,该用户可能位于世界任何地方。

\n

使用.toLocaleString()

\n

它具有比您想象的更多的格式化自定义参数,通过DateTimeFormat中列出的locale和两个参数。它甚至支持不同的日历、语言、格式化年月日的方式等(没有传递的参数将使用用户的默认设置,这可能是理想的。)options

\n

作为开发人员,只需将该时间点值(例如销售活动或竞赛的开始时间)作为UNIX 时间戳数字(即从 1970 年 1 月 1 日开始的秒数,采用 UTC 时区)传递即可。不可知和 DST0agnostic)到客户端,然后执行new Date(timestamp).toLocaleString(). 例如,对于上面的时间点,该值是1636875321000(以毫秒为单位),通过使用此答案+dateWithTimeZone("America/Los_Angeles",2021,10,13,23,35,21)中的函数。

\n
\n

2) 能够在 3 个月后的当地时间上午 9 点向用户发送通知/电子邮件

\n

这是完全不同的要求!就像,非常非常不同!

\n

GMT-8:00 还不够吗?

\n

不!

\n

这只是用户在某个时间点所在的时区,例如“现在,今天”

\n
    \n
  • 您如何知道用户是否有夏令时?(美国的亚利桑那州没有,还有许多其他国家和州,甚至县!)
  • \n
  • 您如何知道用户是否处于 DST 状态?旧金山是冬天(GMT-8)还是阿拉斯加是夏天(同样是 GMT-8)。看到这个巨大的列表吓坏了:https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
  • \n
\n

“PDT”还不够吗?

\n

不!

\n

首先,PDT 甚至不是全年都可以进行的。现在是 11 月,timeanddate.com目前 PDT 上没有位置。您想查看 PST 吗? ”(请阅读我上面的 Medium 文章了解更多详细信息。)

\n

除非您想要从客户端到客户端的 UI 字符串,否则此 PDT/CEST/ 等。不值任何东西!

\n

为什么?因为墨西哥的蒂华纳和美国的旧金山在 6 月份都处于 PDT,但它们的 DST(夏令时)日期不同,因此切换到 PST。你需要知道这一点!

\n

2022年美国夏令时为2022年3月13日至2022年11月6日。墨西哥2022年夏令时日期为2022年4月3日至2022年10月30日。因此,虽然蒂华纳和旧金山在近 93% 的日子里共享“PDT/PST”,但在 7% 的日子里(例如 2022 年 3 月 14 日至 4 月 3 日,以及 10 月 31 日至 11 月 6 日),他们不\不匹配。

\n

因此,即使您知道现在是 11 月并且知道用户处于 PDT,您也无法判断用户设备中的时间(哪个时间戳数字)是 2022 年 4 月 1 日上午 9 点。

\n

附言。如果你想PDTnew Date().toString(). 仅供参考,如果您将计算机的区域设置更改es-MX(西班牙语,这是 13% 的美国人口的语言),您将得到以下结果:

\n
> new Date().toString()\n\'Sun Nov 14 2021 00:47:25 GMT-0800 (hora est\xc3\xa1ndar del Pac\xc3\xadfico)\'\n
Run Code Online (Sandbox Code Playgroud)\n

祝你好运hedP

\n

那我该怎么办呢?

\n

唯一正确的方法是使用 IANA(读“标准”)时区值。这是该维基百科页面的第二栏。它来自:

\n
const timeZoneIANA = Intl.DateTimeFormat().resolvedOptions().timeZone;\n
Run Code Online (Sandbox Code Playgroud)\n

America/Los_Angeles它返回旧金山的IANA 值。这是您应该为用户存储在数据库中的值(如果有的话)。您可以从timezones.json包中获取有关它的各种信息,并将时间从/到该时区转换,加上日期(这很重要),就像这个答案一样。

\n

IE11呢?

\n

IE11 不支持那个Intl....东西。大多数 Polyfill 只是猜测并且不准确。因此,请尝试放弃对 IE11 的支持,或者使用库,并为一些不准确的情况做好准备。

\n
\n

3)我只想知道他们现在的时区偏移量(例如-8:00)

\n

你可能不应该。我想不出你需要这个的任何真正原因。同样,知道今天的这个值并不能告诉您明天这个值会是多少。

\n

无论如何,你总是可以通过以下方式获得该值

\n
new Date().getTimezoneOffset() / 60\n
Run Code Online (Sandbox Code Playgroud)\n

在客户端。

\n

注意:.getTimezoneOffset()不是日期对象的时区偏移量,您正在调用它请阅读文档。

\n

准确地说,它获取传递的 Date 对象(它有一个时间戳,指历史中的单个时间点),然后告诉该点的 UTC 时间和本地时间之间的差异-时间。

\n

同样,这取决于日期。看:

\n
console.log(new Date("6/13/2021").getTimezoneOffset() / 60); // It\'s 7 on a machine that runs in San Francisco\nconsole.log(new Date("11/13/2021").getTimezoneOffset() / 60); // It\'s 8 on a machine that runs in in San Francisco\n
Run Code Online (Sandbox Code Playgroud)\n
\n

有图书馆吗?

\n

以下是支持时区交换的库列表。

\n

但是,请记住,您必须首先解决设计问题,然后再查找代码。时区方面的事情很容易变得复杂,您必须知道“PDT”和“GMT-8”不是全年为用户存储在数据库中的信息/有价值的时区值。:)

\n


dfa*_*dfa 12

尝试getTimezoneOffset()的的Date对象:

var curdate = new Date()
var offset = curdate.getTimezoneOffset()
Run Code Online (Sandbox Code Playgroud)

此方法以分钟为单位返回时区偏移量,即GMT和本地时间之间的差值(以分钟为单位).


小智 11

尝试这个 :

new Date().toLocaleString("en-US",Intl.DateTimeFormat().resolvedOptions().timeZone)
Run Code Online (Sandbox Code Playgroud)

这将在您客户端的浏览器上查找 timeZone。

  • 在 Chrome 88 和 OS X 11.1 上,这似乎不会返回时区。它将当前本地日期和时间作为(本地化)字符串返回:“2/18/2021, 11:04:34 AM” (3认同)

زيا*_*ياد 9

JavaScript的:

var d = new Date();
var n = d.getTimezoneOffset();
var timezone = n / -60;
console.log(timezone);
Run Code Online (Sandbox Code Playgroud)

  • 此答案提供了以前的答案没有提供的内容? (2认同)

Dan*_*scu 9

同时提供偏移量和时区的单行代码是简单地在新的Date对象上调用toTimeString()。从MDN:

toTimeString()方法以美国人可读的形式返回Date对象的时间部分。

问题是时区不是标准的IANA格式。它比“洲/城市” IANA格式更加人性化。试试看:

console.log(new Date().toTimeString().slice(9));
console.log(Intl.DateTimeFormat().resolvedOptions().timeZone);
console.log(new Date().getTimezoneOffset() / -60);
Run Code Online (Sandbox Code Playgroud)

在加利福尼亚州,现在,toTimeString()回报Pacific Daylight Time而国际API返回America/Los_Angeles。在哥伦比亚,你会得到Colombia Standard Time,主场迎战America/Bogota

请注意,此问题的许多其他答案尝试通过调用Date.toString()获得相同的信息。正如MDN解释的那样,这种方法并不可靠:

日期实例是指特定的时间点。调用toString()将以人类可读的格式返回使用美国英语格式的日期。[...]有时需要获取时间部分的字符串;用这种toTimeString()方法可以完成这样的事情。

toTimeString()方法是特别有用的,因为实现ECMA-262标准的发动机可以从所获得的字符串中不同toString()Date对象,该格式是与实现有关的; 简单的字符串切片方法可能无法在多个引擎上产生一致的结果。

  • 这是最好的答案! (3认同)

Dha*_*oni 7

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat

Intl.DateTimeFormat() 构造函数创建 Intl.DateTimeFormat 对象,该对象启用语言敏感的日期和时间格式设置。

Intl.DateTimeFormat().resolvedOptions().timeZone // Asia/Kolkata
Run Code Online (Sandbox Code Playgroud)


kol*_*pto 6

使用moment.js:

moment().format('zz');
Run Code Online (Sandbox Code Playgroud)

  • `z`和`zz`自1.6.0起已被弃用,请参阅http://momentjs.com/docs/#/displaying/format/ (6认同)
  • @brauliobo这些参数不会返回相同的内容.z和zz返回时区,例如CST,但Z和ZZ返回偏移量,例如-0600. (4认同)
  • @MrUpsidown现在是`Z`和`ZZ` (3认同)
  • 虽然 moment.js 在当时是一个很棒的库,但目前还有更小的替代品([dayjs](https://github.com/iamkun/dayjs)、[date-fns](https://date-fns .org/))。[时刻巨大](https://github.com/moment/moment/issues/3376);请不要推荐它用于客户端应用程序。 (3认同)

Fiz*_*han 6

使用,您可以找到当前时区为

console.log(moment().utcOffset()); // (-240, -120, -60, 0, 60, 120, 240, etc.)
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdn.jsdelivr.net/momentjs/2.13.0/moment.min.js"></script>
Run Code Online (Sandbox Code Playgroud)


使用,您可以找到当前时区为

console.log(dayjs().utcOffset()); // (-240, -120, -60, 0, 60, 120, 240, etc.)
Run Code Online (Sandbox Code Playgroud)
<script src="https://unpkg.com/dayjs@1.8.10/dayjs.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

两个API均以分钟为单位返回utc偏移量。

  • “使用dayjs,您可以找到当前时区”并不完全准确-您只会找到[偏移量,而不是时区](/sf/ask/76396071/ offset-in-javascript#comment26646149_1091372)。此外,[Dayjs 不支持时区](https://github.com/iamkun/dayjs/pull/325)。它的 [.utcOffset() 方法](https://github.com/iamkun/dayjs/blob/47bda00df90c0e96a76c082cf80dba9a6c8a8e4e/src/index.js#L319) 是原生`getTimezoneOffset()` 的简单包装。 (2认同)

mik*_*kun 6

正如其他人提到的,要获取时区:

const tz = Intl.DateTimeFormat().resolvedOptions().timeZone
Run Code Online (Sandbox Code Playgroud)

之前没有提到,要获取时区的偏移量,请使用区域设置“ia”(请参阅​​/sf/answers/4498398831/

const getOffset = (tz) => Intl.DateTimeFormat("ia", {
                timeZoneName: "shortOffset",
                timeZone : tz
              })
                .formatToParts()
                .find((i) => i.type === "timeZoneName").value // => "GMT+/-hh:mm"
                .slice(3); //=> +/-hh:mm

 console.log(tz + ' UTC' + getOffset(tz))


 
Run Code Online (Sandbox Code Playgroud)


Abr*_*hin 5

时区(以小时为单位)-

var offset = new Date().getTimezoneOffset();
if(offset<0)
    console.log( "Your timezone is- GMT+" + (offset/-60));
else
    console.log( "Your timezone is- GMT-" + offset/60);
Run Code Online (Sandbox Code Playgroud)

如果您想像评论中提到的那样精确,那么您应该尝试这样-

var offset = new Date().getTimezoneOffset();

if(offset<0)
{
    var extraZero = "";
    if(-offset%60<10)
      extraZero="0";

    console.log( "Your timezone is- GMT+" + Math.ceil(offset/-60)+":"+extraZero+(-offset%60));
}
else
{
    var extraZero = "";
    if(offset%60<10)
      extraZero="0";

    console.log( "Your timezone is- GMT-" + Math.floor(offset/60)+":"+extraZero+(offset%60));
}
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

501946 次

最近记录:

5 年,9 月 前