为什么JavaScript可以处理超过2038年的时间戳?

时间:2013-11-14 14:42:43

标签: javascript php

我们知道使用Javascript Date构造函数的所有日期都是以美国时间1970年1月1日00:00:00(世界时)(UTC)的毫秒数计算的,其中包含86,400,000毫秒的日期。这意味着JS使用UNIX时间戳。我将我的计时器设置为2038年以后的日期(比如2039年11月14日)并运行脚本:

    <script>
      var d = new Date();
      alert(d.getFullYear()+" "+d.getMonth()+" "+d.getDate());
    </script>

它成功警告2039 10 14不像PHP打印“9 Oct,1903 07:45:59”

JS如何处理这个问题?我感到很困惑,感激不尽!

5 个答案:

答案 0 :(得分:11)

32位PHP使用32位整数,其最大值放置了2038年可以表示的最后一个UNIX时间戳。这就是众所周知的Y2K38 problem,几乎影响所有使用UNIX时间戳的32位软件。移动到64位或与其他时间戳表示一起使用的库(在PHP的情况下为DateTime类)解决了这个问题。

Javascript没有整数,只有floats,它没有固有的最大值(但反过来精度较低)。

答案 1 :(得分:4)

Javascript没有整数,只有浮点数(详细信息可以在the standards document中找到)。

这意味着您可以代表一些非常大的数字,但代价是精确度。一个简单的测试就是:

i = 1384440291042
 => 1384440291042
i = 13844402910429
 => 13844402910429
i = 138444029104299
 => 138444029104299
i = 1384440291042999
 => 1384440291042999
i = 13844402910429999
 => 13844402910430000
i = 138444029104299999
 => 138444029104300000
i = 1384440291042999999
 => 1384440291043000000
i = 13844402910429999999
 => 13844402910430000000

正如您所看到的,这个数字并不能保证准确。 The outer limits of integer precision in javascript(你实际上会得到你输入的相同值)是9007199254740992.根据我的转换测试,这将是好的,直到285428751-11-12T07:36:32 + 00:00:)

简单的答案是Javascript内部使用的数据类型比用于C风格epoc的longint(4字节,32位)更大......

答案 2 :(得分:1)

2038年问题仅适用于签名的32位时间戳,PHP和其他一些系统使用这些时间戳。带符号的32位时间戳的范围在2038年以秒为单位。

来自Wikipedia article(强调我的):

  

2038年的问题可能导致某些计算机软件在2038年附近的某个时刻出现故障。该问题会影响所有将系统时间存储为带符号的32位整数的软件和系统。将此数字解释为自1970年1月1日星期四00:00:00 UTC以来的秒数。1可以用这种方式表示的最晚时间是2038年1月19日星期二03:14:07 UTC。 [2] ... 这是由整数溢出引起的。计数器“耗尽”可用数字,“增加”符号位,并报告最大负数(继续向上计数,向零) 。由于错误的计算,这可能会给这些系统的用户带来问题。

在具有更大范围的变量中存储时间戳可以解决问题。

答案 3 :(得分:0)

  

这意味着JS使用UNIX时间戳。

请注意:Unix时间戳自1970年以来为秒。JS时间自1970年以来为毫秒。因此JS时间戳不适合更早的32位int(但JS对此不使用32位int)

答案 4 :(得分:0)

JavaScript的常量为Number.MAX_SAFE_INTEGER

它的值是9007199254740991,所以这也是UNIX时间戳的最大安全值。 9007199254740991秒是〜285616年。 因此,JS可以处理Unix时间戳,直到1月1日大约287586。

哪个足够好。在大多数情况下:-)

  

在此上下文中,安全是指能够精确表示整数并正确比较它们的能力。例如,Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2将计算为true,这在数学上是不正确的。