How to overcome “datetime.datetime not JSON serializable”?

后端 未结 30 2733
梦谈多话
梦谈多话 2020-11-22 03:31

I have a basic dict as follows:

sample = {}
sample[\'title\'] = \"String\"
sample[\'somedate\'] = somedatetimehere


        
相关标签:
30条回答
  • 2020-11-22 04:05

    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;

    0 讨论(0)
  • 2020-11-22 04:05

    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()
    
    0 讨论(0)
  • 2020-11-22 04:07

    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

    0 讨论(0)
  • 2020-11-22 04:09

    Convert the date to a string

    sample['somedate'] = str( datetime.utcnow() )
    
    0 讨论(0)
  • 2020-11-22 04:09

    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)) 
    
    0 讨论(0)
  • 2020-11-22 04:10

    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'
    
    0 讨论(0)
提交回复
热议问题