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

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

I have a basic dict as follows:

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


        
相关标签:
30条回答
  • 2020-11-22 03:59

    A quick fix if you want your own formatting

    for key,val in sample.items():
        if isinstance(val, datetime):
            sample[key] = '{:%Y-%m-%d %H:%M:%S}'.format(val) #you can add different formating here
    json.dumps(sample)
    
    0 讨论(0)
  • 2020-11-22 04:01

    Here is a simple solution to over come "datetime not JSON serializable" problem.

    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)
    

    Output:-> {"date": "2015-12-16T04:48:20.024609"}

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

    Actually it is quite simple. If you need to often serialize dates, then work with them as strings. You can easily convert them back as datetime objects if needed.

    If you need to work mostly as datetime objects, then convert them as strings before serializing.

    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'>
    

    As you can see, the output is the same in both cases. Only the type is different.

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

    I faced this issue today, I found something called pickle. It's a built-in library for serializing python objects and also load it from a pickle file.

    The only difference I found between pickle and json is pickle file is a binary file, where as json is a usual text file.

    And It doesn't cause any issues with datetime objects.

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

    Building on other answers, a simple solution based on a specific serializer that just converts datetime.datetime and datetime.date objects to strings.

    from datetime import date, datetime
    
    def json_serial(obj):
        """JSON serializer for objects not serializable by default json code"""
    
        if isinstance(obj, (datetime, date)):
            return obj.isoformat()
        raise TypeError ("Type %s not serializable" % type(obj))
    

    As seen, the code just checks to find out if object is of class datetime.datetime or datetime.date, and then uses .isoformat() to produce a serialized version of it, according to ISO 8601 format, YYYY-MM-DDTHH:MM:SS (which is easily decoded by JavaScript). If more complex serialized representations are sought, other code could be used instead of str() (see other answers to this question for examples). The code ends by raising an exception, to deal with the case it is called with a non-serializable type.

    This json_serial function can be used as follows:

    from datetime import datetime
    from json import dumps
    
    print dumps(datetime.now(), default=json_serial)
    

    The details about how the default parameter to json.dumps works can be found in Section Basic Usage of the json module documentation.

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

    Generally there are several ways to serialize datetimes, like:

    1. ISO string, short and can include timezone info, e.g. @jgbarah's answer
    2. Timestamp (timezone data is lost), e.g. @JayTaylor's answer
    3. Dictionary of properties (including timezone).

    If you're okay with the last way, the json_tricks package handles dates, times and datetimes including timezones.

    from datetime import datetime
    from json_tricks import dumps
    foo = {'title': 'String', 'datetime': datetime(2012, 8, 8, 21, 46, 24, 862000)}
    dumps(foo)
    

    which gives:

    {"title": "String", "datetime": {"__datetime__": null, "year": 2012, "month": 8, "day": 8, "hour": 21, "minute": 46, "second": 24, "microsecond": 862000}}
    

    So all you need to do is

    `pip install json_tricks`
    

    and then import from json_tricks instead of json.

    The advantage of not storing it as a single string, int or float comes when decoding: if you encounter just a string or especially int or float, you need to know something about the data to know if it's a datetime. As a dict, you can store metadata so it can be decoded automatically, which is what json_tricks does for you. It's also easily editable for humans.

    Disclaimer: it's made by me. Because I had the same problem.

    0 讨论(0)
提交回复
热议问题