Python 3 datetime.fromtimestamp失败1微秒 [英] Python 3 datetime.fromtimestamp fails by 1 microsecond

查看:752
本文介绍了Python 3 datetime.fromtimestamp失败1微秒的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想以微秒的分辨率将数据时间保存为时间戳。但是,似乎Python 3 datetime模块在加载它们时丢失了一微秒。要测试这个,我们创建一个脚本:

I want to save datetimes with microsecond resolution as timestamps. But it seems that Python 3 datetime module lost one microsecond when loading them. To test this let's create a script:

test_datetime.py

from random import randint
from datetime import datetime

now = datetime.now()

for n in range(1000):
    d = datetime(year=now.year, month=now.month, day=now.day,
            hour=now.hour, minute=now.minute, second=now.second,
            microsecond=randint(0,999999))

    ts = d.timestamp()
    d2 = datetime.fromtimestamp(ts)

    assert d == d2, 'failed in pass {}: {} != {}'.format(n, d, d2)

python3 test_datetime.py 总是失败一微秒:

Traceback (most recent call last):
  File "test_datetime.py", line 14, in <module>
    assert d == d2, 'failed in pass {}: {} != {}'.format(n, d, d2)
AssertionError: failed in pass 4: 2014-07-02 11:51:46.984716 != 2014-07-02 11:51:46.984715

这个行为是公认?我们不应该依赖datetime.fromtimestamp,如果我们想要微秒分辨率?

Is this behavior to be accepted? Shouldn't we rely on datetime.fromtimestamp if we want microsecond resolution?

推荐答案

时间戳值是浮点值。浮点值为近似值,因此适用舍入误差。

Timestamp values are floating point values. Floating point values are approximations, and as such, rounding errors apply.

浮动值 1404313854.442585 不精确。这是真的:

A float value of 1404313854.442585 is not precise, for example. It is really:

>>> dt = datetime(2014, 7, 2, 16, 10, 54, 442585)
>>> dt.timestamp()
1404313854.442585
>>> format(dt.timestamp(), '.20f')
'1404313854.44258499145507812500'

非常接近442585,但不太可能。它是刚刚低于 442585,所以当你采取只是小数部分,乘以100万,然后只取整数部分0.991455078125余数被忽略,你最终使用442584。

That's awfully close to 442585, but not quite. It is just below 442585, so when you take just the decimal portion, multiply that by 1 million, then take just the integer portion the 0.991455078125 remainder is ignored and you end up with 442584.

因此,当您将浮点值转换回 datetime 对象时,1微秒圆角错误正常

As such, when you then convert the floating point value back to a datetime object, 1 microsecond rounding errors are normal.

如果需要精度,不要依赖于 float ;或者将微秒值存储为单独的整数,然后使用 dt.fromtimestamp(seconds).replace(microsecond = microseconds)

If you require precision, don't rely on float; perhaps instead store the microsecond value as a separate integer, then use dt.fromtimestamp(seconds).replace(microsecond=microseconds).

您可能会发现拒绝通知 PEP-410(使用decimal.Decimal类型为时间戳在这种情况下启发。 PEP介绍了精确问题,时间戳表示为浮点数。

You may find the rejection notice to PEP-410 (Use decimal.Decimal type for timestamps) enlightening in this context. The PEP touched upon the precision issue with timestamps represented as floats.

这篇关于Python 3 datetime.fromtimestamp失败1微秒的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆