How to overcome "datetime.datetime not JSON serializable"?
The quick solution to serialize datetime
objects in JSON is to use .isoformat()
and json.dumps()
:
The datetime
object is now in a JSON-friendly string format, voila!
Quick transformations with default=str
To convert datetime
objects quickly when precision isn't critical, use default=str
in json.dumps()
:
Heads up! This approach will convert all non-serializable objects to strings which can cause issues during deserialization.
Custom JSON serialization: json_serial
You can specifically handle datetime
objects, preserving their type during deserialization using a custom serialization function:
The json_serial
function ensures datetime
objects become ISO 8601 strings, while raising a fuss (TypeError
) for unhandled types.
Timestamp precision: subclassing json.JSONEncoder
For a more granular control and extendability, create a subclass, DateTimeEncoder
, of json.JSONEncoder
:
Not only does this encoder handles datetime
serilization with precision, but it can be extended to handle more complex types later.
Special mention: json_util
Working with MongoDB? Use pymongo's json_util
for an optimal datetime
handling:
To deserialize, json.loads
with json_util.object_hook
can revert the datetime
objects.
Visualization
Pretend that a datetime
object is like a water balloon trying to fit into a stack of bricks.
Plain JSON
might scream, "No way!", but serializing datetime
helps defuse the tension:
This is incompatible because the water balloon won't stack with the bricks.
However, when we serialize the datetime
:
Voila! The water balloon transformed into a brick (ISO 8601) fits perfectly into the JSON
brick stack.
Precision versus Practicality
.isoformat()
is great but what about precision and deserialization? Let's discuss:
- Full datetime precision: If
datetime
serialization should include microseconds or timezone information, ensure.isoformat()
caters to these. - Deserialization: When you deserialize, if you need the exact
datetime
type back, you'll need a paired parsing step. - Selecting encoders: Choose wisely! Django's built-in
DjangoJSONEncoder
supportsdatetime
but may miss milliseconds.
Understand these aspects to select correctly for your specific needs.
ISO 8601: Making JavaScript Happy
An advantage of serializing datetime
into ISO 8601 format is its compatibility with JavaScript's Date
parsing:
This provides seamless integration with front-end applications and follows best practices in web development.
Was this article helpful?