本文翻译自:How to overcome “datetime.datetime not JSON serializable”?
I have a basic dict as follows: 我有一个基本的命令,如下所示:
sample = {}
sample['title'] = "String"
sample['somedate'] = somedatetimehere
When I try to do jsonify(sample)
I get: 当我尝试执行jsonify(sample)
我得到:
TypeError: datetime.datetime(2012, 8, 8, 21, 46, 24, 862000) is not JSON serializable
What can I do such that my dictionary sample can overcome the error above? 我该怎么做才能使我的词典示例可以克服上述错误?
Note: Though it may not be relevant, the dictionaries are generated from the retrieval of records out of mongodb where when I print out str(sample['somedate'])
, the output is 2012-08-08 21:46:24.862000
. 注意:尽管可能不相关,但字典是从mongodb中检索记录生成的,当我打印出str(sample['somedate'])
,输出为2012-08-08 21:46:24.862000
。
#1楼
参考:https://stackoom.com/question/npQg/如何克服-datetime-datetime无法JSON序列化
#2楼
Updated for 2018 更新于2018
The original answer accommodated the way MongoDB "date" fields were represented as: 原始答案适应了MongoDB“日期”字段表示为:
{"$date": 1506816000000}
If you want a generic Python solution for serializing datetime
to json, check out @jjmontes' answer for a quick solution which requires no dependencies. 如果您想要将datetime
时间序列化为json的通用Python解决方案,请查看@jjmontes的答案以获取无需依赖项的快速解决方案。
As you are using mongoengine (per comments) and pymongo is a dependency, pymongo has built-in utilities to help with json serialization: 当您使用mongoengine(每个注释)并且pymongo是一个依赖项时,pymongo具有内置的实用程序来帮助json序列化:
http://api.mongodb.org/python/1.10.1/api/bson/json_util.html http://api.mongodb.org/python/1.10.1/api/bson/json_util.html
Example usage (serialization): 用法示例(序列化):
from bson import json_util
import json
json.dumps(anObject, default=json_util.default)
Example usage (deserialization): 用法示例(反序列化):
json.loads(aJsonString, object_hook=json_util.object_hook)
Django Django的
Django provides a native DjangoJSONEncoder
serializer that deals with this kind of properly. Django提供了本机DjangoJSONEncoder
序列化程序,可以正确处理这种情况。
See https://docs.djangoproject.com/en/dev/topics/serialization/#djangojsonencoder 参见https://docs.djangoproject.com/en/dev/topics/serialization/#djangojsonencoder
from django.core.serializers.json import DjangoJSONEncoder
return json.dumps(
item,
sort_keys=True,
indent=1,
cls=DjangoJSONEncoder
)
One difference I've noticed between DjangoJSONEncoder
and using a custom default
like this: 我注意到DjangoJSONEncoder
与使用这样的自定义default
之间的一个区别:
import datetime
import json
def default(o):
if isinstance(o, (datetime.date, datetime.datetime)):
return o.isoformat()
return json.dumps(
item,
sort_keys=True,
indent=1,
default=default
)
Is that Django strips a bit of the data: 是Django剥离了一些数据:
"last_login": "2018-08-03T10:51:42.990", # DjangoJSONEncoder
"last_login": "2018-08-03T10:51:42.990239", # default
So, you may need to be careful about that in some cases. 因此,在某些情况下,您可能需要注意这一点。
#3楼
将日期转换为字符串
sample['somedate'] = str( datetime.utcnow() )
#4楼
You have to supply a custom encoder class with the cls
parameter of json.dumps
. 您必须提供一个带有json.dumps
的cls
参数的自定义编码器类。 To quote from the docs : 引用文档 :
>>> 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', ']']
This uses complex numbers as the example, but you can just as easily create a class to encode dates (except I think JSON is a little fuzzy about dates) 这以复数为例,但是您可以轻松地创建一个类来对日期进行编码(但我认为JSON对日期有些模糊)
#5楼
For others who do not need or want to use the pymongo library for this.. you can achieve datetime JSON conversion easily with this small snippet: 对于不需要或想要使用pymongo库的其他人,您可以使用此小片段轻松实现日期时间JSON转换:
def default(obj):
"""Default JSON serializer."""
import calendar, datetime
if isinstance(obj, datetime.datetime):
if obj.utcoffset() is not None:
obj = obj - obj.utcoffset()
millis = int(
calendar.timegm(obj.timetuple()) * 1000 +
obj.microsecond / 1000
)
return millis
raise TypeError('Not sure how to serialize %s' % (obj,))
Then use it like so: 然后像这样使用它:
import datetime, json
print json.dumps(datetime.datetime.now(), default=default)
output: 输出:
'1365091796124'
#6楼
Here is my solution: 这是我的解决方案:
# -*- coding: utf-8 -*-
import json
class DatetimeEncoder(json.JSONEncoder):
def default(self, obj):
try:
return super(DatetimeEncoder, obj).default(obj)
except TypeError:
return str(obj)
Then you can use it like that: 然后,您可以像这样使用它:
json.dumps(dictionnary, cls=DatetimeEncoder)