6

new Date()当谈到夏令时线时,我已经阅读了许多关于 javascript 对象的 StackOverflow 问题——就像它们被交叉时一样。但是,我还没有看到关于这个特定问题的答案或在仍然依赖“unix time”的同时解决它的方法。

我个人选择通过将 javascript 日期作为日期传递给我的 PHP 代码而不是 unix 时间来解决这个问题。然而,挥之不去的问题仍然存在!我已经在 IE8、Chrome 和 FF 上确认了这种行为,所以我假设它对你的行为相同。(更新: OSX 用户可能无法生成此行为)

我的研究;与我的问题最接近的问题:

  • 该用户在 DST 更改前后的特定时间工作。
  • 该用户担心时间的显示取决于用户的时区。该页面上接受的答案提到这getTimezoneOffset是“片状”,这导致我没有深入研究。
  • 请参阅下面我对其他有一些深刻见解的问题的回答

我在 2006 年 11 月 1 日左右生成了一个测试场景。根据您所在的时区,这可能会或可能不会对您起作用。如果我正确理解 javascript 方面,您需要将 PC 的时钟同步到

东部时间(美国和加拿大)并选中“自动调整夏令时时钟”。

我基于 PHP 中的“印第安纳波利斯”时区进行此实验。我的 javascript 结果,当我发现 2006 年 11 月 1 日的 unix 时间比 PHP 生成的时间少一小时(3600 秒)。根据这个页面(谢谢乔恩!)javascript是错误的。

两种语言结果于 2006 年 11 月 6 日重新达成一致

这项研究和其他研究使我相信 Javascript 弄错了它的历史并选择了错误的星期天以从 DST 中“回退”——从而导致了我所看到的差异。

我试图尽可能简化这一点,但仍有不少齿轮在运转。

  1. 这是 PHP 代码和输出,显示了截至 2006 年 11 月 1 日的正确毫秒数。

    date_default_timezone_set("美国/印第安纳州/印第安纳波利斯"); echo "2006 年 11 月 1 日的 Unix 时间是:".strtotime("11/01/2006")."\n"; echo "2006 年 11 月 6 日的 Unix 时间是:".strtotime("11/06/2006");

结果是:

Unixtime for November 1, 2006 is: 1162357200 (where the disagreement lies)
Unixtime for November 6, 2006 is: 1162789200

它们都基于 GMT-0500。

  1. 在 Javascript 中,(请参阅我的jsfiddle **),我调用它new Date,然后getTime()像这样调用它(并删除毫秒):

    新日期("2006/11/01").getTime()/1000 新日期("2006/11/06").getTime()/1000

这会生成值

1162353600 <-- PHP outputs: 1162357200
1162789200 <-- the same as PHP for '2006/11/06'; congruence is restored

这与通过 PHP 输出的 3600 秒(或 1 小时)不同(对于 2006/11/01)。在我的 PHP 应用程序中处理此值(提前一小时)生成前一天(2006 年 10 月 31 日),这是不可接受的,因为它破坏了我的导航。(查看我的特定场景的更多解释

用 Javascript 输出:Date("2006/11/01")不调用getTime()就解开了一些谜团,因为 javascript 揭示了它使用的偏移量GMT-0400

我的jsfiddle ** 实验(也在上面列出)显示了这些结果。

**(您可能需要更改计算机的时区才能看到相同的行为)。

可能发挥作用的是,根据维基百科,2006 年是印第安纳州开始使用 DST 的第一年。无论哪种方式都是一个奇怪的谜题。

由于我已经制定了我的解决方案(通过避免在我的 javascript 中依赖 unix 时间),我想我应该为后代发布这个,希望有人可能知道如何更正 javascript 显示的值。

问题是:如何将 PHP 和 javascript 之间的两个“unix 时间”结果对齐?我将不胜感激了解 DST '线' 周围的情况或一般情况。(我目前假设 DST 线是问题)。

更新:运行 Chrome 的 iMac 生成了 PHP 生成的结果。什么???荒野。对此行为的任何 javascript 端修复看起来都将是一项伟大的事业(或至少是丑陋的)。也许这不是javascript 问题,因为它会根据操作系统(或其他因素?)生成正确答案。

值得注意的是,在这台 iMac 上,我没有强制使用时区,我不确定这台 Apple 电脑是否允许。“自动设置日期和时间”的设置已选中 ( true) 和disabled。时区设置为东部夏令时间。未选中“自动设置时区”框 ( false) 和disabled

我添加了Windows标签以强调它在 OSX 中似乎不是问题。

更新:根据上面链接的网站,我验证了以下所有日期在适当的日期(更新的小提琴)交叉到了一个新的 GMT 偏移量——不像 2006 年的响应是一周的时间。即,在 2007 年 11 月 4 日,它是GMT-4和 2007 年 11 月 5 日,它返回GMT-5

  • 2007 年 3 月 11 日星期日凌晨 2 点 11 月 4 日星期日凌晨 2 点
  • 2008 年 3 月 9 日星期日凌晨 2 点 11 月 2 日星期日凌晨 2 点
  • 2009 年 3 月 8 日星期日凌晨 2:00 11 月 1 日星期日凌晨 2:00
  • 2010 年 3 月 14 日星期日凌晨 2:00 11 月 7 日星期日凌晨 2:00
  • 2011 年 3 月 13 日星期日凌晨 2 点 11 月 6 日星期日凌晨 2 点

最后,如果您知道在 2006 年将此错误提交给 Javascript 所依赖的任何时区源的正确渠道,请这样做并让我知道。

4

2 回答 2

7

首先,印第安纳州的时间非常复杂

但在这种情况下,我认为 Javascript 是错误的。我机器上 Javascript 的输出(已设置时区)在 Chrome 上是“2006 年 11 月 1 日星期三 00:00:00 GMT-0400(东部夏令时间)”和“2006 年 11 月 1 日星期三 00:00:00 EDT”在 Internet Explorer 上,但夏令时于 2006 年 10 月 29 日在印第安纳波利斯结束

.NET 的TimeZoneInfo类给出了相同的结果:

// Ignore the daft ID; it really means Eastern time
var zone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
var local = new DateTime(2006, 11, 1);
Console.WriteLine(zone.GetUtcOffset(local));

输出:

-5:00:00

(所以它知道它不在夏令时。)

同样在 Noda Time(我自己的日期和时间库,它使用 tzdb 数据库)中:

var zone = DateTimeZone.ForId("America/Indiana/Indianapolis");
var instant = new Instant(1162357200 * NodaConstants.TicksPerSecond);
var zoned = new ZonedDateTime(instant, zone);
Console.WriteLine(zoned);

结果:

Local: 01/11/2006 00:00:00 Offset: -05 Zone: America/Indiana/Indianapolis
于 2012-05-09T18:52:24.940 回答
0

唷; 我认为 Jon 有一些很好的观点和确认,即 2006 年 11 月的最初几周,当夏令时开始时(至少在印第安纳州),Javascript 在 Windows 机器上提取了错误的数据库。

我仍然不知道如何在 Javascript 中解决这个难题。但是,由于我的主要问题是 Javascript 和 PHP 之间的“不一致”(毕竟,如果它们在同一天/同一小时更改为 DST,那么我永远不会注意到有问题),解决方案可能是停止依赖其中之一。

这个SO answer虽然没有检索 unixtime,但演示了如果我需要继续依赖 unixtime,我可以如何解决这种紧张局势。恕我直言,这实际上是一个非常巧妙的解决方案。简要总结:通过 AJAX 检索时区信息。这意味着 PHP 将始终同意任何特定日期 00:00:00 的 unixtime,因为它本质上是提供值本身。

但是,这仍然不是问题的真正解决方案:Javascript 正在检索对东部时区何时退出夏令时的错误理解。我仍然很高兴知道人们将如何纠正这种极小而狭窄的不一致窗口。

自从我尝试在 Javascript 中输出正确值的 OSX 机器之后,它甚至会像“可能尚未开发”的 Windows 补丁一样复杂吗?

我怀疑我的场景和这个问题是否相关,但这是我在研究时遇到的一个有趣的错误。在那个问题中,Date 对象——取决于传递的格式——可能会产生一些非常令人惊讶的输出。

如果有人想颠覆对用户计算机时区数据库的依赖来计算正确的日期,这个答案可能会在烹饪和依赖自己的时区数据库方面提供一些帮助。我没有调查过使用这种解决方案,也没有调查过如何覆盖 Javascript 返回的 unixtime 结果,但这是我找到的最接近的答案。我想知道开销会是多少......?如果您可以实施这种类型的解决方案,请务必发布答案——这可能是我最初问题的真正答案。

于 2012-05-10T12:19:46.000 回答