JavaScript、时区和夏令时

6
欢迎来到本周的 又一时区问题 专题:
我已经在 Stack Overflow 上阅读了不少文章,试图使用 moment.js 和 date.js 来实现我的需求,但自始至终一直感到沮丧。如果有人能帮忙或指出我无法找到的 SO 上的重复问题,那就太好了。
我有一个页面,其中会显示一系列时间,例如:7:28、7:38、7:48。我知道这些时间是上午还是下午。这些时间总是以美国/纽约为基准(它们不会随着夏令时的变化而改变,因为相应事件总是发生在那个时间,不考虑夏令时)。我们把它们称为“日程表”。我想要突出显示即将到来的时间。
  • 对于生活在美国/纽约的人来说,这很简单。
  • 对于生活在美国/洛杉矶的人来说,这也不太困难(假设我的逻辑没问题)。
    • 我可以获取计算机在美国/洛杉矶的当前时间,将其转换为 UTC,然后确定美国/洛杉矶是否正在观察夏令时,以及美国/纽约当前应该是 -0400 还是 -0500,将其应用于 UTC 并进行比较。这会有点麻烦,因为你仍然需要处理一个基于美国/洛杉矶时间的日期,而不是实际更改 Date 对象的时区,但我有一种可靠的方法可以从 UTC 时间回滚(或前进)小时数。

然而,当我试图从一个根本不观察夏令时的计算机中确定是否正在观察夏令时时,会发生什么情况呢?

据我所知,JavaScript 只能为当前时区创建 Date 对象,然后对 DST 的任何确定都是基于该 Date 对象的。

我应该无动于衷吗?这些时间主要只与居住在美国/纽约的人相关。我只是想构建一个应用程序,以便从其他时区查看时是有意义的,在不观察夏令时的国家,当时间是凌晨 3 点,而在美国/纽约是下午 2 点时,“日程表”可以突出显示即将发生的是下午 2:05 而不是上午 3:05。


你能否在jsfiddle上创建一个最小化的失败示例来展示问题行为?如果能提供一个失败的qunit测试将会很棒。 - Ben Taitelbaum
http://jsfiddle.net/bBdL5/ - 为了看到这个现象,需要首先在一个使用DST的时区观察页面。您将看到两个偏移量返回不同。然后将您的时区设置为不使用DST的时区,退出浏览器并重新启动。请参见以下两个图像:http://i.imgur.com/pxqIj.jpg和http://i.imgur.com/ZaXi6.jpg-我不知道除了我展示的方法之外还有什么其他方法来确定是否发生了DST(这就是Date.js的做法) - Aaron
现在我正在构建示例,我想我可以硬编码一些日期来帮助我确定是否为夏令时,但是如果我想要转换的地区停止观察夏令时,那么这将需要代码维护才能成功。 - Aaron
在编程中翻译如下内容:在不同的时区,同一天中的某个时间可能是不同的一天(例如:纽约时区转移时间之前的一天,在同一时间的北京市就是时区转移当天)。不仅如此,似乎即使是遵守夏令时的国家也可能在不同的日期遵守它们(欧盟和美国在三月份的日期不同),因此即使从在遵守夏令时的时区进行计算,有时仍会出现错误的结果。 - Aaron
但我不知道是否将其设置为-0500或-0400,因为我不知道美国/纽约当前是否正在观察夏令时。 - Aaron
显示剩余2条评论
2个回答

6

所有与时间相关的比较都应该使用您实例的getTime()方法来完成。它返回自UTC纪元以来的毫秒数,不受DST影响。您将getTime()的值发送到服务器。然后,您的客户端脚本将把这个值转换回JavaScript Date对象,如下所示:

mydate = new Date(longmillisFromAnotherTZ);

然后使用mydate中的任何方法来显示您想要的日期格式。这有意义吗?我没能看到有什么问题。不过,我很乐意澄清任何疑问。

编辑:

为了100%的清晰...

如果两个不同的客户端需要在不同的时区中将其操作显示给对方,我建议您仅使用(new Date()).getTime()的值,然后将其保存到服务器。 然后,服务器会将此值发送到每个相应的客户端。 客户端随后负责在自己的适当语言环境中进行显示。

另外,如果您需要一个获取时区和偏移量的好库, getTimezoneOffset()已知不稳定,您应该查看这个库:http://www.pageloom.com/automatic-timezone-detection-with-javascript


好的,没有直接的服务器/JavaScript通信,但我知道你的意思。我确实可以让服务器输出自UTC时代以来的毫秒数,以及标准化为EST时间,然后我可以完全忽略这些EST时间,并与服务器在页面上隐藏的内容进行比较。这通常是你想要的吗?我不想误解,因为已经很难用文字表达我遇到的问题了 :) - Aaron
好的,我明白你的意思。在这种情况下,服务器在页面上以 EST 显示文本,而客户端可以在任何地方。虽然我需要在页面上显示 EST 时间,但我肯定可以使用服务器获取这些时间的 UTC 自纪元时间,并将它们放入数据属性中,然后可以用 JavaScript 进行比较。这应该可行,并且与您建议始终使用 getTime() 并完全忽略时区转换相符。 - Aaron
1
有趣的是,我在屏幕抓取一个流行的体育网站时也遇到了同样的问题;p 我做了你所提出的方法。 - JP Richardson

5
啊,我终于明白您的意思了。您想表达的意思是,根据用户电脑上的时间,类似于“纽约市当前时间为_”,虽然文档中支持setTimezone("EDT"),但似乎不支持setTimezone("America/New York")。您要么需要硬编码日期以在EDT和EST之间切换(基于从用户电脑获取的当前GMT时间),或使用第三方API(或在服务器端执行此操作)。

这绝对是解释这个问题的一种优秀而简明的方式。在我决定哪个答案最好之前,我还要再给这个问题一点时间,但是现有的两个答案肯定值得点赞,所以现在就点赞了... - Aaron

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接