我有一个基本的字典如下:
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。
我可能不是百分百正确,
这是实现序列化的简单方法
#!/usr/bin/python
import datetime,json
sampledict = {}
sampledict['a'] = "some string"
sampledict['b'] = datetime.datetime.now()
print sampledict # output : {'a': 'some string', 'b': datetime.datetime(2017, 4, 15, 5, 15, 34, 652996)}
#print json.dumps(sampledict)
'''
output :
Traceback (most recent call last):
File "./jsonencodedecode.py", line 10, in <module>
print json.dumps(sampledict)
File "/usr/lib/python2.7/json/__init__.py", line 244, in dumps
return _default_encoder.encode(obj)
File "/usr/lib/python2.7/json/encoder.py", line 207, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/lib/python2.7/json/encoder.py", line 270, in iterencode
return _iterencode(o, 0)
File "/usr/lib/python2.7/json/encoder.py", line 184, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: datetime.datetime(2017, 4, 15, 5, 16, 17, 435706) is not JSON serializable
'''
sampledict['b'] = datetime.datetime.now().strftime("%B %d, %Y %H:%M %p")
afterdump = json.dumps(sampledict)
print afterdump #output : {"a": "some string", "b": "April 15, 2017 05:18 AM"}
print type(afterdump) #<type 'str'>
afterloads = json.loads(afterdump)
print afterloads # output : {u'a': u'some string', u'b': u'April 15, 2017 05:18 AM'}
print type(afterloads) # output :<type 'dict'>
我可能不是百分百正确,
这是实现序列化的简单方法
#!/usr/bin/python
import datetime,json
sampledict = {}
sampledict['a'] = "some string"
sampledict['b'] = datetime.datetime.now()
print sampledict # output : {'a': 'some string', 'b': datetime.datetime(2017, 4, 15, 5, 15, 34, 652996)}
#print json.dumps(sampledict)
'''
output :
Traceback (most recent call last):
File "./jsonencodedecode.py", line 10, in <module>
print json.dumps(sampledict)
File "/usr/lib/python2.7/json/__init__.py", line 244, in dumps
return _default_encoder.encode(obj)
File "/usr/lib/python2.7/json/encoder.py", line 207, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/lib/python2.7/json/encoder.py", line 270, in iterencode
return _iterencode(o, 0)
File "/usr/lib/python2.7/json/encoder.py", line 184, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: datetime.datetime(2017, 4, 15, 5, 16, 17, 435706) is not JSON serializable
'''
sampledict['b'] = datetime.datetime.now().strftime("%B %d, %Y %H:%M %p")
afterdump = json.dumps(sampledict)
print afterdump #output : {"a": "some string", "b": "April 15, 2017 05:18 AM"}
print type(afterdump) #<type 'str'>
afterloads = json.loads(afterdump)
print afterloads # output : {u'a': u'some string', u'b': u'April 15, 2017 05:18 AM'}
print type(afterloads) # output :<type 'dict'>
其实很简单。
如果您需要经常序列化日期,那么可以将它们作为字符串使用。如果需要,您可以轻松地将它们转换回datetime对象。
如果您主要需要作为datetime对象工作,那么在序列化之前将它们转换为字符串。
import json, datetime
date = str(datetime.datetime.now())
print(json.dumps(date))
"2018-12-01 15:44:34.409085"
print(type(date))
<class 'str'>
datetime_obj = datetime.datetime.strptime(date, '%Y-%m-%d %H:%M:%S.%f')
print(datetime_obj)
2018-12-01 15:44:34.409085
print(type(datetime_obj))
<class 'datetime.datetime'>
如您所见,两种情况下的输出是相同的。只是类型不同。
我的解决方案是……
from datetime import datetime
import json
from pytz import timezone
import pytz
def json_dt_serializer(obj):
"""JSON serializer, by macm.
"""
rsp = dict()
if isinstance(obj, datetime):
rsp['day'] = obj.day
rsp['hour'] = obj.hour
rsp['microsecond'] = obj.microsecond
rsp['minute'] = obj.minute
rsp['month'] = obj.month
rsp['second'] = obj.second
rsp['year'] = obj.year
rsp['tzinfo'] = str(obj.tzinfo)
return rsp
raise TypeError("Type not serializable")
def json_dt_deserialize(obj):
"""JSON deserialize from json_dt_serializer, by macm.
"""
if isinstance(obj, str):
obj = json.loads(obj)
tzone = timezone(obj['tzinfo'])
tmp_dt = datetime(obj['year'],
obj['month'],
obj['day'],
hour=obj['hour'],
minute=obj['minute'],
second=obj['second'],
microsecond=obj['microsecond'])
loc_dt = tzone.localize(tmp_dt)
deserialize = loc_dt.astimezone(tzone)
return deserialize
好,现在来做一些测试。
# Tests
now = datetime.now(pytz.utc)
# Using this solution
rsp = json_dt_serializer(now)
tmp = json_dt_deserialize(rsp)
assert tmp == now
assert isinstance(tmp, datetime) == True
assert isinstance(now, datetime) == True
# using default from json.dumps
tmp = json.dumps(datetime.now(pytz.utc), default=json_dt_serializer)
rsp = json_dt_deserialize(tmp)
assert isinstance(rsp, datetime) == True
# Lets try another timezone
eastern = timezone('US/Eastern')
now = datetime.now(eastern)
rsp = json_dt_serializer(now)
tmp = json_dt_deserialize(rsp)
print(tmp)
# 2015-10-22 09:18:33.169302-04:00
print(now)
# 2015-10-22 09:18:33.169302-04:00
# Wow, Works!
assert tmp == now