Python | mktime溢出错误
我在网上到处搜索,但找不到合适的解决方案来处理这个问题。
OverflowError: mktime argument out of range
导致这个异常的代码是:
t = (1956, 3, 2, 0, 0, 0, 0, 0, 0)
ser = time.mktime(t)
我想知道这个异常的真正原因,有些人说日期不在有效范围内,但我觉得这没什么意义。如果有范围的话,那是什么呢?这是否取决于我们使用的系统?我也想知道一个好的解决方案来解决这个问题。
谢谢。
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库函数不支持某个值以下的时间。
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 的评论中提到的那样。