【问题标题】:Python fromtimestamp OSErrorPython fromtimestamp OSError
【发布时间】:2016-09-26 11:20:21
【问题描述】:

由于某种原因,在使用 fromtimestamp 构造日期时间时,当我使用小于 -43200(-12 小时)的负数时,我得到一个“OSError [Errno22] Invalid Argument”。 我在 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 来简化时区信息,但没有它也会出现错误。

【问题讨论】:

  • 这里你的两行是相似的,第一行打印值第二次抛出错误。所以我认为有一些缩进错误或其他东西..所以尝试使用 except OSError as e: 捕获异常然后输入你的错误..
  • 不是语法错误。此示例有意简单地显示导致错误所需的最小值。我最初在 for 循环中找到了限制。
  • 对我来说同样的问题是bug in python 3.6

标签: python


【解决方案1】:

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

【讨论】:

  • –1 表示不必要的屈尊。实际上,将fromtimestamp 与负数一起使用通常可以正常工作,但它取决于平台。
  • @wim –1 使用 –1 代替 -1
【解决方案2】:

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

【讨论】:

  • 当时间戳等于 0 时,我在 Windows 10(和 python 3.6.5)上遇到了同样的问题。
  • 只需将时间戳除以 1000。我在 Windows 10 和 Linux 上进行了测试,都可以正常工作并给出正确答案。
  • 我和@EdwardWeinert 你知道了吗?
  • 这是 1969 年 OP 案例的正确答案
  • @Primoz 为答案添加了可能的解决方法。我认为正确的结果是datetime.datetime(1949, 1, 1, 0, 0),而不是datetime.datetime(1949, 1, 1, 1, 0),不是吗?也许您的机器配置为 UTC+1 时区,而您使用的是本地时间。
【解决方案3】:

@wim's answer 是正确的,但其他到达这里的人可能有兴趣测试它(如果您愿意,可以调整范围):

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)

【讨论】:

  • Running on Python ver.3.9.1 on Windows 10 Smallest accepted Unix timestamp by Windows: '1' (1970-01-01 01:00:01)
【解决方案4】:

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

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)

结果是我们所期望的。

【讨论】:

  • 我需要看到这一点。这就是我得到错误的确切原因。我在 Python 中使用 JSON PowerShell 日期,它们使用毫秒。
【解决方案5】:

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

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

【讨论】:

  • 这对我有帮助,谢谢。
【解决方案6】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-12
    • 2016-08-22
    • 1970-01-01
    • 2010-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多