在JavaScript中给定TimeZone字符串的情况下计算UTC偏移量 [英] Calculate the UTC offset given a TimeZone string in JavaScript

查看:183
本文介绍了在JavaScript中给定TimeZone字符串的情况下计算UTC偏移量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用标准JS库(ECMA5),不使用momentjs或外部库,如何在给定TimeZone字符串(例如欧洲/罗马"或美国/洛杉矶")的情况下计算UTC偏移量?

Using the standard JS library (ECMA5), without using momentjs or external libs, how do you calculate the UTC offset given a TimeZone string such as "Europe/Rome" or "America/Los_Angeles"?

UTC偏移量可能取决于它是否是DST,因此,如果解决方案需要将本地客户端日期转换为指定的时区字符串,则将是有意义的.目的只是想知道与UTC的偏移量.

UTC Offsets may depend on whether it is DST or not, so it would make sense if the solution required converting the local client date to the specified Timezone String. The goal is just to know the offset from UTC.

function getUtcOffset(timezone) {
  // return int value. 
  // > 0 if +GMT 
  // < 0 if -GMT.
}

推荐答案

ECMAScript中没有任何功能(

There is no function in ECMAScript (ECMA-262) that can perform the operation you requested. This is simply because standard ECMAScript does not know anything about time zones other than that of the local computer, and UTC.

但是,在支持ECMAScript国际化API( ECMA- 402 ),并且完全支持IANA时区数据库标识符,您可以将以下功能结合在一起:

However, in browsers that support the ECMAScript Internationalization API (ECMA-402), and fully support the IANA time zone database identifiers, you can hack together a function like this:

function getTimezoneOffset(d, tz) {
  const a = d.toLocaleString("ja", {timeZone: tz}).split(/[/\s:]/);
  a[1]--;
  const t1 = Date.UTC.apply(null, a);
  const t2 = new Date(d).setMilliseconds(0);
  return (t2 - t1) / 60 / 1000;
}

这将在当前版本的Chrome中运行,也许还会在其他一些地方运行.但肯定不能保证它在任何地方都能正常工作.特别是,它不能在任何版本的Internet Explorer浏览器中使用.

This will work in current versions of Chrome, and perhaps in a few other places. but it is certainly not guaranteed to work everywhere. In particular, it won't work in Internet Explorer browsers of any version.

用法示例(在Chrome中):

Example usage (in Chrome):

getTimezoneOffset(new Date(2016, 0, 1), "America/New_York") // 300
getTimezoneOffset(new Date(2016, 6, 1), "America/New_York") // 240
getTimezoneOffset(new Date(2016, 0, 1), "Europe/Paris") // -60
getTimezoneOffset(new Date(2016, 6, 1), "Europe/Paris") // -120

关于此特定功能的一些注意事项:

A few things to note about this particular function:

  • 就像我提到的那样,它不会在所有地方都起作用.最终,由于所有浏览器都将赶上现代标准,但目前还不会.

  • Like I mentioned, It's not going to work everywhere. Eventually, as all browsers catch up to modern standards it will, but it won't currently.

您传递的日期确实会影响结果.这是由于夏时制和其他时区异常.您可以仅使用new Date()传递 current 日期,但是结果将根据调用该函数的时间而变化.请参见时区标签Wiki 中的时区!=偏移量".

The date you pass in will indeed affect the result. This is due daylight saving time and other time zone anomalies. You can pass the current date just with new Date(), but the result will change based on when you call the function. See "time zone != offset" in the timezone tag wiki.

此函数的结果与Date.getTimezoneOffset相同-以分钟为单位,正值是UTC的 West .如果您使用的是ISO8601偏移量,则需要将其转换为小时并反转符号.

The results of this function are the same as Date.getTimezoneOffset - in terms of minutes, with positive values being West of UTC. If you are working with ISO8601 offsets, you'll need to convert to hours and invert the sign.

该功能依赖于toLocaleString功能的时区格式化功能.我选择了'ja'区域性,因为日期部分已经按照数组的正确顺序排列了.这确实是一个hack.理想情况下,将有一个API使您可以在格式化时访问时区信息,而不必将其绑定到语言环境.不幸的是,该特定API的设计者犯了将时区与语言环境相关联的错误.这是其他几种来自各种语言的API所犯的错误,不幸的是,此处已将其包含在JavaScript中.

The function relies on the time zone formatting functionality of the toLocaleString function. I picked the 'ja' culture, because the date parts were already in the correct order for the array. This is a hack indeed. Ideally there would be an API that would let you access time zone information without binding it to a locale when formatting. Unfortunately, the designers of this particular API have made the mistake of associating time zone with locale. This is a mistake that's been made in a few other APIs from various languages, and unfortunately was carried into JavaScript here.

简单地说:ECMA-402中唯一的时区功能是在格式化字符串时应用时区,这是设计缺陷,恕我直言.

Restated plainly: The only time zone functionality in ECMA-402 is to apply a time zone when formatting a string, which is a design flaw, IMHO.

上面的示例用法部分中有一个错误,它说明了此API错误的部分原因.具体来说,当您 create Date对象时,无法指定时区.我传递的1月1日和7月1日是在 local 时区中创建的,而不是在指定的时区中创建的.因此,输出可能与您在过渡附近所期望的不完全相同.为解决此问题,可能会更多地利用它,但是我将作为练习留给您.

There's a bug in my example usage section above, that exemplifies part of why this API is a mistake. Specifically, there's no way to specify a time zone when you create a Date object. The Jan 1st and July 1st dates I pass in are created in the local time zone, not in the time zone specified. Therefore, the output may not be exactly what you expect near a transition. This could be hacked even more to work around this problem, but I will leave that as an exercise to you.

再次-尽管此答案满足了所要求的标准,但由于不涉及任何外部库,因此我强烈建议再次在任何生产代码中使用它.如果您打算对此做任何重要的事情,我会使用我在此处列出的其中一个库.我个人的喜好是 moment.js

Again - Though this answer satisfies the criteria asked for, as there are no external libraries involved, I strongly recommend against using this in any production code. If you're planning on doing anything important with this, I'd use one of the libraries I listed here. My personal preference is for moment.js with the moment-timezone addon, because I help maintain that library. YMMV

这篇关于在JavaScript中给定TimeZone字符串的情况下计算UTC偏移量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆