javascript错误地决定夏时制时间线 – 一个2006年的例子

当涉及到夏令时时间线时,我已经阅读了javascript new Date()对象上的许多StackOverflow问题 – 就像它们交叉时一样。 但是,我还没有看到有关这个特定问题的答案,或者依靠unix时间”来解决这个问题的方法。

我个人select通过将javascriptdate作为date传递给我的PHP代码而不是unix时间来解决此问题。 然而,唠叨的问题仍然存在! 我已经在IE8,Chrome和FF上证实了这种行为,所以我假设它对你的行为是一样的。 ( 更新: OSX用户可能无法生成此行为)

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

  • 此用户正在围绕DST更改的特定时间进行工作。
  • 该用户担心根据用户的时区显示时间。 在该页面上接受的答案提到getTimezoneOffset是“片状”,导致我没有深入研究。
  • 在下面的其他问题上看到我的答案,有一些很好的见解

我已经在2006年11月1日左右生成了一个testing场景。根据所处的时区,这可能也可能不一样。如果我正确理解了javascript方面,则需要将PC时钟同步到

东部时间(美国和加拿大),然后选中“自动调整夏时制时钟”。

我将这个实验基于PHP的“印第安纳波利斯”时区。 我的javascript结果,当我find2006年11月1日的Unix时间是一个小时的PHP产生(3600秒)。 根据这个页面 (感谢乔恩!)javascript是错误的。

这两种语言的结果在11/06/2006 重新达成一致

这个和其他的研究使我相信,JavaScript的历史错误,并select了错误的星期天“退后”出DST – 从而导致我所看到的差异。

我试图尽可能地简化这一点,但运动中仍然有不less齿轮。

1) 这里是PHP代码和输出 ,显示直到2006年1月11日为止的正确的毫秒数。

 date_default_timezone_set("America/Indiana/Indianapolis"); echo "Unixtime for November 1, 2006 is: ".strtotime("11/01/2006")."\n"; echo "Unixtime for November 6, 2006 is: ".strtotime("11/06/2006"); 

结果是:

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

他们都是基于GMT-0500。

2)在Javascript中,(见我的jsfiddle **),我调用new Date ,然后getTime()像这样(并删除毫秒):

 new Date("2006/11/01").getTime()/1000 new Date("2006/11/06").getTime()/1000 

这会生成值

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

这是从输出通过PHP的3600秒 – 或一个小时的差异 (2006/11/01)。 在我的PHP应用程序中处理的值(一小时前)在前一天(2006/10/31)生成,这是不可接受的,因为它打破了我的导航前进。 ( 更多的解释我的特殊情况 )

用Javascript输出: Date("2006/11/01")不调用getTime()清除一些神秘的东西,因为javascript会显示它使用GMT-0400的偏移量。

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

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

根据维基百科,2006年是印第安纳州开始使用DST 的第一年 。 一个奇怪的拼图任何一种方式。

由于我已经制定出我的解决scheme(通过避免依靠在JavaScript中的unix时间),我想我应该张贴这个后代,希望有人可能知道如何纠正值的JavaScript显示。

问题是:如何将PHP和JavaScript之间的两个“unix时间”结果进行alignment? 我将不胜感激地学习如何在DST'线'或一般。 (我目前假设DST线是问题)。

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

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

我添加了Windows标签来强调它在OSX中似乎没有问题。

更新:根据上面链接的网站,我证实, 所有以下date跨越到适当的date(更新小提琴)新的GMT偏移 – 不像2006年的答复是一个星期了 。 也就是说,2007年11月4日, GMT-4和2007年11月5日, GMT-5

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

最后,如果你知道在2006年提交这个错误的正确渠道,无论Javascript依赖于什么时区,请这样做,让我知道这一点。

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

但在这种情况下,我相信Javascript是错误的。 在我的机器(设置时区)上的Javascript的输出为“Wed Nov 01 2006 00:00:00 GMT-0400(Eastern Daylight Time)”和“2006年11月1日00:00:00 EDT”在Internet Explorer上 – 但夏令时于10月29日在印第安纳波利斯于2006年结束 。

.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 

唷; 我认为Jon有一些优秀的观点和证实,即在2006年11月的最初几周,夏时制开始时,至少在印第安纳州,JavaScript正在Windows机器上拉错数据库。

我仍然不知道如何去解决Javascript中的这个困境。 但是,由于我的主要问题是JavaScript和PHP之间的“不一致”(毕竟,如果在同一天/同一个小时内更改为DST,那么我从来没有注意到有问题),解决方案可能是停止依靠这一个或另一个。

这回答 ,虽然不取回unixtime,演示如何我可能去解决这种紧张局势,如果我需要继续依靠unixtime。 这实际上是一个非常漂亮的解决方案,恕我直言。 它的简短摘要:通过AJAX检索时区信息。 这意味着PHP总是会在任何特定的日子在00:00:00同意unixtime,因为它本质上是提供价值的。

但是,这仍然不是一个真正的解决方案:Javascript正在检索对东部时区何时退出夏令时的错误理解 。 我仍然会很高兴知道如何去纠正这个非常小而狭隘的不一致的窗口。

难道它甚至可能像“可能尚未开发”的Windows补丁一样复杂,因为我尝试在Javascript中输出正确值的OSX机器?

我怀疑我的情况和这个问题是相关的,但这是我在研究过程中遇到的一个迷人的错误。 在这个问题中,Date对象 – 取决于传递的格式 – 可能会产生一些非常令人惊讶的输出。

如果有人想颠覆用户计算机的时区分贝来计算正确的日期, 这个答案可能会提供一些帮助,并依靠自己的时区数据库。 我还没有调查这种解决方案的工作,也没有如何重写由Javascript返回的unixtime结果,但这是我找到的最接近的答案。 我不知道会有什么开销…? 如果你可以实现这种类型的解决方案一定要发表一个答案 – 这可能是我原来的问题的真实答案。