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

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

I have a basic dict as follows:

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


        
相关标签:
30条回答
  • 2020-11-22 03:48
    def j_serial(o):     # self contained
        from datetime import datetime, date
        return str(o).split('.')[0] if isinstance(o, (datetime, date)) else None
    

    Usage of above utility:

    import datetime
    serial_d = j_serial(datetime.datetime.now())
    if serial_d:
        print(serial_d)  # output: 2018-02-28 02:23:15
    
    0 讨论(0)
  • 2020-11-22 03:51

    My quick & dirty JSON dump that eats dates and everything:

    json.dumps(my_dictionary, indent=4, sort_keys=True, default=str)
    
    0 讨论(0)
  • 2020-11-22 03:51

    Convert the date to string

    date = str(datetime.datetime(somedatetimehere)) 
    
    0 讨论(0)
  • 2020-11-22 03:52

    If you are on both sides of the communication you can use repr() and eval() functions along with json.

    import datetime, json
    
    dt = datetime.datetime.now()
    print("This is now: {}".format(dt))
    
    dt1 = json.dumps(repr(dt))
    print("This is serialised: {}".format(dt1))
    
    dt2 = json.loads(dt1)
    print("This is loaded back from json: {}".format(dt2))
    
    dt3 = eval(dt2)
    print("This is the same object as we started: {}".format(dt3))
    
    print("Check if they are equal: {}".format(dt == dt3))
    

    You shouldn't import datetime as

    from datetime import datetime
    

    since eval will complain. Or you can pass datetime as a parameter to eval. In any case this should work.

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

    My solution ...

    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    
    

    Ok, now some tests.

    # 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
    
    0 讨论(0)
  • 2020-11-22 03:55

    This library superjson can do it. And you can easily custom json serializer for your own Python Object by following this instruction https://superjson.readthedocs.io/index.html#extend.

    The general concept is:

    your code need to locate the right serialization / deserialization method based on the python object. Usually, the full classname is a good identifier.

    And then your ser / deser method should be able to transform your object to a regular Json serializable object, a combination of generic python type, dict, list, string, int, float. And implement your deser method reversely.

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