I have a basic dict as follows:
sample = {}
sample[\'title\'] = \"String\"
sample[\'somedate\'] = somedatetimehere
if you are using python3.7, then the best solution is using
datetime.isoformat() and
datetime.fromisoformat(); they work with both naive and
aware datetime
objects:
#!/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() }
return super().default(obj)
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))
output:
{"now": {"_isoformat": "2000-01-01T00:00:00-08:00"}}
True
if you are using python3.6 or below, and you only care about the time value (not
the timezone), then you can use datetime.timestamp()
and
datetime.fromtimestamp()
instead;
if you are using python3.6 or below, and you do care about the timezone, then
you can get it via datetime.tzinfo
, but you have to serialize this field
by yourself; the easiest way to do this is to add another field _tzinfo
in the
serialized object;
finally, beware of precisions in all these examples;
The simplest way to do this is to change the part of the dict that is in datetime format to isoformat. That value will effectively be a string in isoformat which json is ok with.
v_dict = version.dict()
v_dict['created_at'] = v_dict['created_at'].isoformat()
This Q repeats time and time again - a simple way to patch the json module such that serialization would support datetime.
import json
import datetime
json.JSONEncoder.default = lambda self,obj: (obj.isoformat() if isinstance(obj, datetime.datetime) else None)
Than use json serialization as you always do - this time with datetime being serialized as isoformat.
json.dumps({'created':datetime.datetime.now()})
Resulting in: '{"created": "2015-08-26T14:21:31.853855"}'
See more details and some words of caution at: StackOverflow: JSON datetime between Python and JavaScript
Convert the date to a string
sample['somedate'] = str( datetime.utcnow() )
The json.dumps method can accept an optional parameter called default which is expected to be a function. Every time JSON tries to convert a value it does not know how to convert it will call the function we passed to it. The function will receive the object in question, and it is expected to return the JSON representation of the object.
def myconverter(o):
if isinstance(o, datetime.datetime):
return o.__str__()
print(json.dumps(d, default = myconverter))
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:
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'