Python fromtimestamp OSError

问题描述 投票:0回答:7

出于某种原因,在使用 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来简化时区信息,但是没有它也会报错

python datetime unix-timestamp oserror
7个回答
66
投票

如果您收到此错误并且您没有使用明显错误的时间戳,请检查您的单位。

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)

结果是我们所期望的


24
投票

要解决此问题,请将时间戳值除以 1000。

在 Windows 中,时间戳数字乘以 1000。


20
投票

如果时间戳超出平台 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

11
投票

@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)

0
投票

迟到的贡献,但我认为重要的是要强调这是 1) 特定于平台和 2) 可能存在与平台无关的解决方案。

引用自文档

fromtimestamp()
可能引发
OverflowError
,如果时间戳超出平台 C
localtime()
gmtime()
函数支持的值范围,并且
OSError
localtime()
gmtime()
失败。这通常被限制在 1970 年到 2038 年之间。

“仅限于 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

-1
投票

时间也可以以微秒为单位,因为时间戳值除以 1000000


-8
投票

时间戳是自 1970 年 1 月 1 日以来的秒数,它始终为正值。

© www.soinside.com 2019 - 2024. All rights reserved.