标签:python datetime unix-timestamp python-3-x python-3-4
我想以微秒分辨率保存日期时间作为时间戳.但似乎Python 3 datetime模块在加载它们时会丢失一微秒.为了测试这个,我们创建一个脚本:
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总是失败1微秒:
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吗?
解决方法:
时间戳值是浮点值.浮点值是近似值,因此,舍入误差适用.
例如,浮点值1404313854.442585不精确.它确实是:
>>> dt = datetime(2014, 7, 2, 16, 10, 54, 442585)
>>> dt.timestamp()
1404313854.442585
>>> format(dt.timestamp(), '.20f')
'1404313854.44258499145507812500'
这非常接近442585,但并不完全.它刚好低于442585,所以当你只取小数部分时,乘以1百万,然后只取整数部分0.991455078125余数被忽略,最终得到442584.
因此,当您将浮点值转换回datetime对象时,1微秒的舍入错误是正常的.
如果您需要精度,请不要依赖浮子;或许将微秒值存储为单独的整数,然后使用dt.fromtimestamp(seconds).replace(microsecond = microseconds).
在这种情况下,您可能会发现rejection notice至PEP-410 (Use decimal.Decimal type for timestamps)的启发性. PEP触及精度问题,时间戳表示为浮点数.
标签:python,datetime,unix-timestamp,python-3-x,python-3-4 来源: https://codeday.me/bug/20190624/1278212.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。