【问题标题】:Why do timestamps have a limit to 2038?为什么时间戳限制为 2038?
【发布时间】:2011-08-18 06:16:30
【问题描述】:

我刚刚在运行日历脚本时发现,PHP 中的时间戳限制为 2038。这到底是什么意思?为什么是 2038 而不是 2050 或 2039?如果时间戳只计算给定日期(1970 年)的秒数,为什么要限制?

【问题讨论】:

标签: php timestamp year2038


【解决方案1】:

限制是由大多数 C 库用于表示该计数的 4 字节有符号整数强加的。快速数学(假设 365 天年,不完全正确):

2147483648 seconds ~ 68.1 years

这也意味着下限约为 1900。一些库已经开始引入 64 位 epoch 计数,但目前还很少。

【讨论】:

  • 为什么他们不能添加另一个 int 并在达到限制时求和?
  • @Charliepiga 查看我的更新答案。这是一项正在进行的工作,但鉴于对大多数人来说暂时不会成为问题,因此进展缓慢。
  • 是的,但为什么要限制呢?难道他们不能只添加类似 if (timestamp > limit) { add another int 并从那里开始新的计数,添加 int1 + int2 以获得总数 } 吗?那会让我们再过 68 年……
  • @Charliepiga PHP 在某些方面受到它所依赖的 C 库的限制。当您开始尝试将 UNIX 时间戳转换为实际的人类可读日期/时间时,时间尤其是一个非常棘手的话题。去看看任何日期/时间库的邮件列表。我知道我在 nodatime 邮件列表上听了一段时间后就放弃了。
  • @Charliepiga 同样,所有值都必须在某个地方有限制。没有办法在有限空间中存储无限数据(可悲!)。使用 64b 整数作为时间计数可以表示巨大的时间跨度,但正如我所说,目前缺乏 C 端的支持。如果您足够幸运,能够针对这些 C 标准库之一编译 PHP,那么如果我正确阅读了文档中的各行之间的内容,那么您实际上不应该有这个限制。
【解决方案2】:

32 位整数的最大值为 2,147,483,647。如果你加上 +1,你会得到 -2,147,483,647。从 01-01-1970 00:00:00 算起的 2,147,483,647 秒是 2038 年 1 月 19 日。如果再增加一秒,就会得到 1902 年某处的日期。

【讨论】:

    【解决方案3】:

    由于 32 位机器上 INT 数据类型的限制

    http://php.net/manual/en/function.mktime.php

    来自 php.net: "mktime() 和 gmmktime() 接受的最大可能日期取决于当前位置的时区。

    例如,32 位时间戳溢出发生在 2038-01-19T03:14:08+0000Z。但是,如果您在 UTC -0500 时区(例如北美的 EST),则溢出前的最大接受时间(对于 Windows 上的旧 PHP 版本)是 2038-01-18T22:14:07-0500Z,无论无论您是将其传递给 mktime() 还是 gmmktime()。"

    【讨论】:

      【解决方案4】:

      我的猜测是它存储在固定数量的位中,这意味着时间戳可以得到多大的限制。我们可以做一些数学来弄清楚。

      【讨论】:

        猜你喜欢
        • 2017-01-31
        • 1970-01-01
        • 2013-03-11
        • 1970-01-01
        • 1970-01-01
        • 2021-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多