在Javascript中使用不同的时区 [英] Working with different timezones in Javascript

查看:78
本文介绍了在Javascript中使用不同的时区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个基于云的应用程序,该应用程序为世界各地的用户广泛处理日期和时间值。



在JavaScript中考虑一个场景,其中机器在印度(GMT + 05:30),我必须显示一个在加利福尼亚时区(GMT-08:00)运行的时钟。



在这种情况下,我必须获取一个新的日期对象,



let india_date = new Date()



添加它的时区偏移值,



let uts_ms = india_date.getTime()+ india_date.getTimezoneOffset()



添加加利福尼亚的时区偏移值,



let california_ms = utc_ms + getCaliforniaTimezoneOffsetMS()



最后是日期对象。



let california_date:日期=新日期(california_ms)



有没有办法直接处理这些时间区域而不必一次又一次地转换值?

解决方案

首先,让我们谈谈您问题中的代码。


  let india_date = new Date()


您已将此变量命名为 india_date ,但是 Date 对象仅在代码在计算机上运行时才会反映印度。设置为印度的时区。如果它在具有不同时区的计算机上运行,​​它将反映该时区。请记住,在内部, Date 对象仅跟踪基于UTC的时间戳。在调用需要本地时间的函数和属性时应用本地时区,而不是在创建 Date 对象时应用。


加上时区偏移值

  let uts_ms = india_date.getTime()+ india_date。 getTimezoneOffset()


此方法不正确。 getTime()已经返回基于UTC的时间戳。您无需添加本地偏移量。 (而且,缩写是UTC,而不是UTS。)


现在添加加利福尼亚的时区偏移值

  let california_ms = utc_ms + getCaliforniaTimezoneOffsetMS()


同样,添加偏移量是不正确的。另外,与印度不同,加利福尼亚州实行夏令时,因此,一年中的部分时间偏移量为 480 (UTC-8),一年中的部分时间偏移量为 420 (UTC-7)。任何功能,例如 getCaliforniatimezoneOffsetMS 都需要将时间戳作为参数传递才能生效。


最后是日期对象

  let california_date:日期=新日期(california_ms)


Date 构造函数为传递了数字时间戳,必须使用UTC。传递此 california_ms 时间戳实际上只是在选择其他时间点。您无法更改 Date 对象的行为,以使其仅通过添加或减去偏移量即可使用其他时区。对于需要本地时间的任何函数,例如 .toString()等,它仍将使用其运行时所在的本地时区。

在只有一种情况下,这种调整才有意义,这是一种称为时代转移的技术。调整时间戳以将基本纪元从正常的 1970-01-01T00:00:00Z 移开,从而允许人们利用 Date 对象的UTC函数(例如 getUTCHours 等)。问题是:一旦转移,您将永远无法在该 Date 对象上使用任何本地时间函数,或将其传递给任何期望<$ c $的对象c> Date 对象是普通对象。正确完成时代转移是使 Moment.js 之类的库的力量。 此处是正确完成时代转移的另一个示例。



但是在您的示例中,您进行了平移操作(错误两次),然后使用 Date 对象,就像它正常,没有转移。这只会导致错误,在 toString 输出中显示的时区很明显,并且在数学上会在本地时区和预期目标时区的任何DST转换附近出现。通常,您不想采用这种方法。



相反,请在如何将JavaScript日期初始化为特定时区。其中列出了您的选项。谢谢。


I am working on a cloud based application which deals extensively with date and time values, for users across the world.

Consider a scenario, in JavaScript, where my machine is in India (GMT+05:30), and I have to display a clock running in California's timezone (GMT-08:00).

In this case I have to get a new date object,

let india_date = new Date()

add it's time zone offset value,

let uts_ms = india_date.getTime() + india_date.getTimezoneOffset()

add california's timezone offset value,

let california_ms = utc_ms + getCaliforniaTimezoneOffsetMS()

and finally the date object.

let california_date: Date = new Date(california_ms)

Is there any way to directly deal with these kinds of time zones without having to convert the values again and again?

解决方案

First, let's talk about the code in your question.

let india_date = new Date()

You have named this variable india_date, but the Date object will only reflect India if the code is run on a computer set to India's time zone. If it is run on a computer with a different time zone, it will reflect that time zone instead. Keep in mind that internally, the Date object only tracks a UTC based timestamp. The local time zone is applied when functions and properties that need local time are called - not when the Date object is created.

add it's timezone offset value

let uts_ms = india_date.getTime() + india_date.getTimezoneOffset()

This approach is incorrect. getTime() already returns a UTC based timestamp. You don't need to add your local offset. (also, the abbreviation is UTC, not UTS.)

Now add california's timezone offset value

let california_ms = utc_ms + getCaliforniaTimezoneOffsetMS()

Again, adding an offset is incorrect. Also, unlike India, California observes daylight saving time, so part of the year the offset will be 480 (UTC-8), and part of the year the offset will be 420 (UTC-7). Any function such as your getCaliforniatimezoneOffsetMS would need to have the timestamp passed in as a parameter to be effective.

and finally the date object

let california_date: Date = new Date(california_ms)

When the Date constructor is passed a numeric timestamp, it must be in terms of UTC. Passing it this california_ms timestamp is actually just picking a different point in time. You can't change the Date object's behavior to get it to use a different time zone just by adding or subtracting an offset. It will still use the local time zone of where it runs, for any function that requires a local time, such as .toString() and others.

There is only one scenario where this sort of adjustment makes sense, which is a technique known as "epoch shifting". The timestamp is adjusted to shift the base epoch away from the normal 1970-01-01T00:00:00Z, thus allowing one to take advantage of the Date object's UTC functions (such as getUTCHours and others). The catch is: once shifted, you can't ever use any of the local time functions on that Date object, or pass it to anything else that expects the Date object to be a normal one. Epoch shifting done right is what powers libraries like Moment.js. Here is another example of epoch shifting done correctly.

But in your example, you are shifting (twice in error) and then using the Date object as if it were normal and not shifted. This can only lead to errors, evident by the time zone shown in toString output, and will arise mathematically near any DST transitions of the local time zone and the intended target time zone. In general, you don't want to take this approach.

Instead, read my answer on How to initialize a JavaScript Date to a particular time zone. Your options are listed there. Thanks.

这篇关于在Javascript中使用不同的时区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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