I’ve run in to this situation a few times and end up having to query my gBrain for the answer. When using json as a transport from python to html/javascript, I frequently end up needing to move date and time data. However, the builtin json module is not happy when you ask it to serialize a date/time object.
>>> json.dumps(datetime.datetime.now()) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python2.6/json/__init__.py", line 230, in dumps return _default_encoder.encode(obj) File "/usr/lib/python2.6/json/encoder.py", line 367, in encode chunks = list(self.iterencode(o)) File "/usr/lib/python2.6/json/encoder.py", line 317, in _iterencode for chunk in self._iterencode_default(o, markers): File "/usr/lib/python2.6/json/encoder.py", line 323, in _iterencode_default newobj = self.default(o) File "/usr/lib/python2.6/json/encoder.py", line 344, in default raise TypeError(repr(o) + " is not JSON serializable") TypeError: datetime.datetime(2011, 12, 1, 0, 50, 53, 152215) is not JSON serializable
So this means we need to figure out a work around. The trick is to let the json module know what it should do with a date/time object while leaving the rest of it in place. So, no replacing the default handler.
What we need to do is subclass the JSONEncoder and override the default method
class JSONEncoder(json.JSONEncoder): def default(self, obj): if hasattr(obj, 'isoformat'): #handles both date and datetime objects return obj.isoformat() else: return json.JSONEncoder.default(self, obj)
Using the hasattr and looking for ‘isoformat’ method will allow this to handle both date objects and datetime objects. So all that is left to demonstrate is how to put it together with the json.dumps method.
>>> json.dumps(datetime.datetime.now(), cls=JSONEncoder) '"2011-12-01T00:58:34.479929"'
Ok, so now you have this ISO formatted string containing date information, how do you get that converted to a javascript date object once it has been transmitted across the abyss and now resides in a javscript callback function?
var d = new Date("2011-12-01T00:58:34.479929");
Happy Data Slinging!