'Serialize datetime.datetime object as JSON

Currently working on a quick little project in python and am attempting to encode an object into a JSON string. I've done this several times before without any problem except for now. Usually I just do the following.

def ClassToEncode :
    def __init__(self, arg1, arg2, ..., argn) :
        self.attr1 = arg1
        self.attr2 = arg2
        ...
        self.attrn = argn

     ...
     def toJSON(self) :
         return json.dumps(self, default=lambda o: o.__dict__)

But the problem is that one of my class attributes is a datetime.datetime object and I am being thrown the following error

AttributeError: 'datetime.datetime' object has no attribute '__dict__'

Any thoughts or wraparounds that could enable the functionality of including the datetime attribute into the JSON output??

Thanks in advance!



Solution 1:[1]

You can use the isoformat() method on a datetime object to convert it to an ISO-8601-formatted time string, then serialize it as JSON just fine. On the other end, call datetime.datetime.strptime() on the formatted string to convert it back into a datetime object:

>>> from datetime import datetime as dt
>>> now = dt.now()
>>> now
datetime.datetime(2014, 9, 4, 3, 19, 44, 214096)
>>> isonow = now.isoformat()
>>> isonow
'2014-09-04T03:19:44.214096'
>>> format = "%Y-%m-%dT%H:%M:%S.%f"
>>> newtime = dt.strptime(isonow, format)
>>> newtime
datetime.datetime(2014, 9, 4, 3, 19, 44, 214096)

Solution 2:[2]

Another way is to modify your toJSON() method to use a customized dictionary in which you customize the data:

import datetime

def ClassToEncode :
    def __init__(self, arg1, arg2, ..., argn) :
        self.attr1 = arg1
        self.attr2 = arg2
        ...
        self.attrn = datetime.datetime.utcnow()

     ...
     def customDict(self):
        dup = self.__dict__.copy()
        # configure dup to contain fields that you want to send
        dup['attrn'] = self.createdAt.isoformat() # datetime object
        del dup['attr2'] # Some private field you may want to hide
        return dup
     def toJSON(self):
        return json.dumps(self, default=lambda o: o.customDict())

Solution 3:[3]

While the accepted answer works great. If you don't need any date formatting you could quickly get away with direct string conversion.

So something like below should work

str(datetime.datetime.now())

json.dumps should be able to serialize this string now.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 MattDMo
Solution 2 rouble
Solution 3 Darshan Kumar