出于某种原因,在使用 fromtimestamp 构建日期时间时,我得到了一个
“OSError [Errno22] 无效参数”
当我使用小于 -43200(-12 小时)的负数时。 我在 Win7 64 位和 python 3.5.1 上。这是产生错误的代码。
>>> import datetime
>>> import pytz
>>> datetime.datetime.fromtimestamp(-43200, pytz.utc)
datetime.datetime(1969, 12, 31, 12, 0, tzinfo=<UTC>)
>>> datetime.datetime.fromtimestamp(-43201, pytz.utc)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 22] Invalid argument
示例中使用了pytz来简化时区信息,但是没有它也会报错
如果您收到此错误并且您没有使用明显错误的时间戳,请检查您的单位。
fromtimestamp
期望以秒为单位的时间戳,而以毫秒为单位获取时间戳是很常见的(例如,我在尝试解析从日历小部件中的 Moment.js 生成的时间戳时发现了这一点)。
以时间戳 1523443804214 为例——现在是 2018 年 4 月 11 日,也就是我发这篇帖子前大约 15 分钟。根据Epoch Converter,没问题,但是注意:“假设这个时间戳是毫秒:”.
在 Python 中,这会返回一个 OSError:
In [15]: datetime.fromtimestamp(1523443804214.0)
---------------------------------------------------------------------------
OSError Traceback (most recent call last)
<ipython-input-15-0c8efd251031> in <module>()
----> 1 datetime.fromtimestamp(1523443804214.0)
然而,如果我们除以一千:
In [17]: datetime.fromtimestamp(1523443804.214)
Out[17]: datetime.datetime(2018, 4, 11, 11, 50, 4, 214000)
结果是我们所期望的
要解决此问题,请将时间戳值除以 1000。
在 Windows 中,时间戳数字乘以 1000。
如果时间戳超出平台 C
localtime()
或 gmtime()
函数支持的值范围,datetime.fromtimestamp()
可能会像您看到的那样引发异常。
在 Windows 平台上,这个范围有时会限制在 1970 年到 2038 年之间。我在 Linux 系统上从未见过这个问题。
如果您在 Windows 上有负时间戳
t
并且遇到此错误,这里有一个解决方法:
from datetime import datetime, timedelta
datetime.fromtimestamp(0) + timedelta(seconds=t) # localtime
datetime.utcfromtimestamp(0) + timedelta(seconds=t) # utc
@wim 的回答 是正确的,但是到达这里的其他人可能有兴趣测试它(如果您愿意,可以调整范围):
import datetime
import platform
print(
"Running on Python ver.{} on {} {}\n" \
.format(
platform.python_version(),
platform.system(),
platform.release()
)
)
for timestamp in range(1, 100000000):
try:
dt = datetime.datetime.fromtimestamp(timestamp)
except:
pass
else:
break
print(
"Smallest accepted Unix timestamp by {}: '{}' ({})" \
.format(platform.system(), timestamp, dt)
)
我得到的是:
A:\src\X.utilities>test.py
Running on Python ver.3.6.1 on Windows 7
Smallest accepted Unix timestamp by Windows: '86400' (1970-01-02 02:00:00)
迟到的贡献,但我认为重要的是要强调这是 1) 特定于平台和 2) 可能存在与平台无关的解决方案。
引用自文档:
可能引发fromtimestamp()
,如果时间戳超出平台 COverflowError
或localtime()
函数支持的值范围,并且gmtime()
在OSError
或localtime()
失败。这通常被限制在 1970 年到 2038 年之间。gmtime()
“仅限于 1970 年到 2038 年的年份”基本上意味着代表秒的带符号 32 位整数的正范围。请注意,这不是 Unix 时间 的一般限制。然而,负数可能会失败,例如在下面的代码中,
Python 3.10
在Windows 10
上:
from datetime import datetime
print(datetime.fromtimestamp(-86400)) # 1969-12-31
>>>
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 22] Invalid argument
与平台无关的替代方案是
from datetime import datetime, timedelta
print(datetime(1970,1,1)+timedelta(seconds=-86400))
>>>
1969-12-31 00:00:00
时间也可以以微秒为单位,因为时间戳值除以 1000000
时间戳是自 1970 年 1 月 1 日以来的秒数,它始终为正值。