我有一个基本的字典如下:
sample = {}
sample['title'] = "String"
sample['somedate'] = somedatetimehere
当我尝试做jsonify(sample)时,我得到:
TypeError: datetime.datetime(2012, 8, 8, 21, 46, 24, 862000) is not JSON serializable
我该怎么做才能使我的字典样本克服上面的错误呢?
注意:虽然它可能不相关,字典是从mongodb的记录检索中生成的,当我打印出str(sample['somedate'])时,输出是2012-08-08 21:46:24.862000。
如果您正在使用python3.7,那么最好的解决方案是使用
datetime.isoformat()和
datetime.fromisoformat ();他们与天真的和
感知datetime对象:
#!/usr/bin/env python3.7
from datetime import datetime
from datetime import timezone
from datetime import timedelta
import json
def default(obj):
if isinstance(obj, datetime):
return { '_isoformat': obj.isoformat() }
raise TypeError('...')
def object_hook(obj):
_isoformat = obj.get('_isoformat')
if _isoformat is not None:
return datetime.fromisoformat(_isoformat)
return obj
if __name__ == '__main__':
#d = { 'now': datetime(2000, 1, 1) }
d = { 'now': datetime(2000, 1, 1, tzinfo=timezone(timedelta(hours=-8))) }
s = json.dumps(d, default=default)
print(s)
print(d == json.loads(s, object_hook=object_hook))
输出:
{"now": {"_isoformat": "2000-01-01T00:00:00-08:00"}}
True
如果您使用的是python3.6或以下版本,并且您只关心时间值(不是
),然后您可以使用datetime.timestamp()和
datetime.fromtimestamp()而不是;
如果您使用的是python3.6或以下版本,并且您确实关心时区,那么
你可以通过datetime获取。Tzinfo,但是您必须序列化这个字段
自己;类中添加另一个字段_tzinfo是最简单的方法
序列化的对象;
最后,要注意所有这些例子的精确性;
我的解决方案(我认为不那么冗长):
def default(o):
if type(o) is datetime.date or type(o) is datetime.datetime:
return o.isoformat()
def jsondumps(o):
return json.dumps(o, default=default)
然后使用jsondumps而不是json.dumps。它将打印:
>>> jsondumps({'today': datetime.date.today()})
'{"today": "2013-07-30"}'
如果你想,以后你可以添加其他特殊情况,通过一个简单的默认方法。例子:
def default(o):
if type(o) is datetime.date or type(o) is datetime.datetime:
return o.isoformat()
if type(o) is decimal.Decimal:
return float(o)
这里有一个简单的解决方案来克服“datetime不可JSON序列化”
问题。
enco = lambda obj: (
obj.isoformat()
if isinstance(obj, datetime.datetime)
or isinstance(obj, datetime.date)
else None
)
json.dumps({'date': datetime.datetime.now()}, default=enco)
输出:-> {"date": "2015-12-16T04:48:20.024609"}
您必须使用json.dumps的cls参数提供一个自定义编码器类。引用文件中的内容:
>>> import json
>>> class ComplexEncoder(json.JSONEncoder):
... def default(self, obj):
... if isinstance(obj, complex):
... return [obj.real, obj.imag]
... return json.JSONEncoder.default(self, obj)
...
>>> dumps(2 + 1j, cls=ComplexEncoder)
'[2.0, 1.0]'
>>> ComplexEncoder().encode(2 + 1j)
'[2.0, 1.0]'
>>> list(ComplexEncoder().iterencode(2 + 1j))
['[', '2.0', ', ', '1.0', ']']
这里使用了复数作为示例,但是您也可以轻松地创建一个类来编码日期(除了我认为JSON对于日期有点模糊)