python - bson.json_util 日期时间编码和解码最佳实践

标签 python datetime pymongo bson

我正在尝试使用 pymongo 的 bson 实用程序对 python 日期时间对象进行编码和解码。 这里的最佳做法是什么?

>>> from bson import json_util
>>> import datetime
>>> utcnow = datetime.datetime.utcnow()
>>> x = json_util.dumps({'now': utcnow})
>>> json_util.loads(x)['now'] == utcnow
False

>>> json_util.loads(x)['now'] - utcnow
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't subtract offset-naive and offset-aware datetimes

>>> json_util.loads(x)['now'].replace(tzinfo=None) - utcnow
datetime.timedelta(-1, 86399, 999088)

>>> datetime.datetime.utcfromtimestamp(1424297808578 / 1000) == json_util.loads(x)['now'].replace(tzinfo=None)
True

^ 这真的是最好的方法吗? 或者编写自己的编码/解码并使用 json 库?

最佳答案

似乎 bson 舍入到毫秒:

>>> from datetime import datetime
>>> import bson # $ pip install bson
>>> d = datetime.utcnow(); d, abs(d - bson.loads(bson.dumps({'utcnow': d}))['utcnow'].replace(tzinfo=None))

(datetime.datetime(2015, 2, 18, 23, 54, 47, 733092), datetime.timedelta(0, 0, 92))

这是一个documented behavior :

UTC datetime - The int64 is UTC milliseconds since the Unix epoch.

如果您需要微秒:您可以存储自 Unix 纪元以来的整数微秒:

from datetime import datetime

td = utc_dt - datetime(1970, 1, 1) 
micros = td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6

将 Unix 纪元以来的微秒转换回表示 UTC 时间的原始日期时间对象:

from datetime import datetime, timedelta

utc_dt = datetime(1970, 1, 1) + timedelta(microseconds=micros)

int64 ( "\x12" ) 足以表示具有微秒分辨率的 Unix 时间(无论如何它都超出了 datetime 范围)。

注意:POSIX 时间戳“忘记”闰秒,例如:

import time

tt = time.strptime("2015-07-01 01:59:60", "%Y-%m-%d %H:%M:%S")
ts_leap = time.mktime(tt)
tt = time.strptime("2015-07-01 02:00:00", "%Y-%m-%d %H:%M:%S")
ts_after = time.mktime(tt)
assert ts_leap == ts_after # assuming "right" timezone is not used

如果你关心微秒;你应该找出你的系统在闰秒前后做了什么。

普通计算机上的时间 ( hardware clocks, software timers ) 不是很准确,因此在许多情况下毫秒分辨率应该足够了,例如,如果您使用 ntp 来同步计算机之间的时间,那么 NTP v3 is accurate to 1-2ms in a LAN and 10s of ms in WAN nets .

尽管有时您希望保留输入中的数字,即使它们不准确也是如此。

关于python - bson.json_util 日期时间编码和解码最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28595338/

相关文章:

C# 用时区解析日期时间

c# - DateTime.TryParse 所有可能的日期类型

sql - 从日期范围生成天数

python - mongodb - 需要处理海量数据,只有一个服务器实例

python - 使用 SSH 在 shell 中启动 Python 脚本

Python:如何遍历行 block

python - 在需要非贪婪匹配的情况下匹配正则表达式

python - python 中的元组列表

python - Pymongo $in 查询不工作

mongodb - 使用 pymongo 和自定义 _id 字段更新插入