【问题标题】:Maximum value of timestamp时间戳最大值
【发布时间】:2018-02-18 08:50:45
【问题描述】:

我在 Windows 10 x64 上使用 Python 3.6.0。

刚刚发现time.ctime(seconds)中,seconds参数有一个隐含的最大值,即32536799999,几乎等于2^34.92135

这是最大值吗?

错误信息只是说它是一个无效的号码。

>>> import time
>>> time.ctime(32536799999)
>>> 'Mon Jan 19 15:59:59 3001'
>>> time.ctime(32536799999+1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 22] Invalid argument

我搜索并查看了 Python 文档,但没有找到任何相关信息。我将在我实验室的 Ubuntu 上检查这个问题。

【问题讨论】:

  • time.ctime 只是调用一些操作系统提供的函数。文档说time.localtime(s) == time.asctime(time.localtime(s)),所以我会看到这些调用中的哪一个在 Windows 上失败。
  • 请不要发布代码或数据的图像。欢迎来到 SO - 请花时间阅读 How to Askminimal reproducible example
  • 这很有趣,因为根据 Windows 文档,最大值实际上应该已经在 3000-12-31T23:59:59
  • 嗯,Python 3.6.2 (v3.6.2:5fd33b5, Jul 8 2017, 04:57:36) [MSC v.1900 64 bit (AMD64)] on win32 &gt;&gt;&gt; time.ctime(32536799999) 'Mon Jan 19 09:59:59 3001'Python 3.5.3 (default, Sep 9 2017, 23:18:15) [MSC v.1900 64 bit (AMD64)] on win32 也一样。
  • @wwii 非常感谢您告诉我,马上修改。

标签: python windows time


【解决方案1】:

time 文档没有提到任何限制,但 datetime documentation 有:

fromtimestamp() 可能会引发 OverflowError,如果时间戳超出平台 C localtime()gmtime() 函数支持的值范围,并且在 localtime()gmtime() 失败时出现 OSError

[...]

Naive datetime 实例被假定为表示本地时间,并且此方法依赖于平台 C mktime() 函数来执行转换。由于在许多平台上datetime 支持的值范围比mktime() 更广泛,因此此方法可能会在很长一段时间内提高OverflowError

然后我们前往Windows documentation

_localtime64,它使用__time64_t 结构,允许在协调世界时 (UTC) 3000 年 12 月 31 日 23:59:59 之前表示日期,而 _localtime32 表示截至 23:59 的日期:59 2038 年 1 月 18 日,UTC。

localtime 是一个内联函数,其计算结果为_localtime64time_t 等价于__time64_t。如果您需要强制编译器将time_t 解释为旧的32 位time_t,您可以定义_USE_32BIT_TIME_T。这样做会导致localtime 评估为_localtime32。不建议这样做,因为您的应用程序可能会在 2038 年 1 月 18 日之后失败,并且在 64 位平台上是不允许的。

所有与时间相关的函数(包括ctime)都以相同的方式工作。因此,您可以在 Windows 10 上的时间戳之间可靠转换的最大日期是 3000-12-31T23:59:59Z。

尝试获取独立于平台的最大时间戳is difficult

【讨论】:

    【解决方案2】:

    我正在使用 3.6.1 |Continuum Analytics, Inc.| (default, May 11 2017, 13:09:58) \n[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] 在 Windows 10 机器上运行的 Ubuntu 16.04 VM 中。

    我分解了你对其组件的 ctime 调用,以进行调查,但我没有遇到相同的最大值。

    >>> time.asctime(time.localtime(32536799999-1))
    'Mon Jan 19 02:59:58 3001'
    >>> time.asctime(time.localtime(32536799999+1))
    'Mon Jan 19 03:00:00 3001'
    >>> time.asctime(time.localtime(32536799999+10))
    'Mon Jan 19 03:00:09 3001'
    >>> time.asctime(time.localtime(32536799999+10000))
    'Mon Jan 19 05:46:39 3001'
    >>> time.asctime(time.localtime(32536799999+1000000))
    'Fri Jan 30 16:46:39 3001'
    >>> time.asctime(time.localtime(32536799999+1000000000))
    'Thu Sep 27 05:46:39 3032'
    >>> time.ctime(32536799999+1000000000)
    'Thu Sep 27 05:46:39 3032'
    >>> time.asctime(time.gmtime(32536799999-1))
    'Mon Jan 19 07:59:58 3001'
    >>> time.asctime(time.gmtime(32536799999+1))
    'Mon Jan 19 08:00:00 3001'
    >>> time.asctime(time.gmtime(32536799999+1000000000))
    'Thu Sep 27 09:46:39 3032'
    

    从 3.6.0 到 3.6.1 修复了某些问题,或者您的机器有一些有趣的问题。

    我确实在 3.6.1 中看到了以下与时间相关的变化: https://www.python.org/dev/peps/pep-0495/ 我想知道你碰巧使用的时间是否恰好落入了折叠或间隙?您能否尝试在您的系统上增加 1 小时多一点,看看它是否再次生效?

    【讨论】:

    • 看来这并不能提供有希望的答案,因为您仍在调查中,您应该将其放入 cmets
    • 在我的声望达到 50 之前,我无法直接对问题发表评论,而且我认为我的详细信息不适合发表评论。我做了一些重要的工作来调查并提供了至少一个部分答案,包括进一步调查的方向,所以我想我会把它留给希望为提问者或其他可能到达这里的人提供一些答案价值搜索。
    • 我们遇到了同样的问题,我们赢得了特权
    • 确实,我通过回答参与了这个过程。我之前提供的以前的答案在这里和那里为我赢得了一些积分(以及感谢您的帮助)。我希望我建议的答案,包括文档链接,以及如何使用它来测试提问者的特定设置的说明,将帮助提问者确认我的回答是否正确识别了问题。如果没有,我相信我已经为任何通过搜索相关问题最终来到这里的人提供了有用的信息。
    • 你在 Ubuntu 上运行它,而不是 Windows。
    【解决方案3】:

    这一定和你安装的Python有关,版本3.5,我从来没有遇到过这样的错误:

    >>> time.ctime(32536799999)
    'Mon Jan 19 07:59:59 3001'
    >>> time.ctime(32536799999+1)
    'Mon Jan 19 08:00:00 3001'
    >>> time.ctime(32536799999+9999999999999999)
    'Thu Feb 13 01:46:38 316890386'
    >>> time.ctime(32536799999+99999999999999999)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    OSError: [Errno 75] Value too large for defined data type
    

    即使我处理一个巨大的数字,它也会抛出一个不同的error

    【讨论】:

    • 在 3.6 中,在 Windows 上,datetime.datetime.max.timestamp() 引发 OSError: [Errno 22] Invalid argument。你得到一个不同的,因为你在 3.5。
    猜你喜欢
    • 2012-04-03
    • 1970-01-01
    • 2018-09-12
    • 2017-05-18
    • 2016-09-24
    • 1970-01-01
    • 2019-01-16
    • 2018-07-13
    • 2017-05-12
    相关资源
    最近更新 更多