Python | mktime溢出错误

21 投票
2 回答
24738 浏览
提问于 2025-04-15 20:51

我在网上到处搜索,但找不到合适的解决方案来处理这个问题。

OverflowError: mktime argument out of range

导致这个异常的代码是:

 t = (1956, 3, 2, 0, 0, 0, 0, 0, 0)
 ser = time.mktime(t)

我想知道这个异常的真正原因,有些人说日期不在有效范围内,但我觉得这没什么意义。如果有范围的话,那是什么呢?这是否取决于我们使用的系统?我也想知道一个好的解决方案来解决这个问题。

谢谢。

2 个回答

2

python time 模块

虽然这个模块总是可以使用,但并不是所有的功能在所有平台上都能用。这个模块里大部分的功能其实是调用了和它同名的平台C库函数。有时候查看一下平台的文档会很有帮助,因为这些函数在不同平台上的具体表现可能会有所不同。

时间的起点叫做“纪元”,这个起点是和平台有关的。对于Unix系统来说,纪元是1970年1月1日,00:00:00(UTC)。如果你想知道某个平台的纪元是什么,可以查看time.gmtime(0)的结果。

https://docs.python.org/3/library/time.html

Windows 10:

>>> time.gmtime(0)
time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0)

>>> list((ix for ix in time.gmtime(0)))
[1970, 1, 1, 0, 0, 0, 3, 1, 0]

>>> time.mktime(time.gmtime(0))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: mktime argument out of range

在Windows 10上,C库函数不支持某个值以下的时间。

27

time.mktime 是调用平台 C 库中的 mktime 函数。比如,你发的代码在我的 Mac OS X 上运行得很好,虽然它返回了一个负数,因为这个日期是在 Unix 纪元之前。所以,问题的原因可能是你使用的平台的 mktime 实现不支持 Unix 纪元之前的日期。你可以使用 Python 的 datetime 模块来构建一个对应于上述日期的 datetime 对象,然后把它和表示 Unix 纪元的另一个 datetime 对象相减,最后用计算出来的 timedelta 对象来获取自纪元以来的秒数:

from datetime import datetime
epoch = datetime(1970, 1, 1)
t = datetime(1956, 3, 2)
diff = t-epoch
print diff.days * 24 * 3600 + diff.seconds

更新: 如果你使用的是 Python 2.7 或更高版本,你可以简单地使用 print diff.total_seconds(),正如 Chad Miller 的评论中提到的那样。

撰写回答