How can I overcome "datetime.datetime not JSON serializable"?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Python’s built-in json module can serialize strings, numbers, booleans, lists, and dictionaries, but it does not know what to do with a datetime.datetime object by default. That is why json.dumps raises TypeError unless you convert the value into a JSON-friendly representation first.
Convert datetime to a String
The simplest fix is to convert the value to a string before serialization. ISO 8601 is usually the best choice because it is standard, sortable, and widely understood.
This works because the dictionary now contains only JSON-native types.
The trade-off is that the conversion happens before json.dumps, so every caller must remember to do it consistently.
Use the default Hook in json.dumps
A more reusable pattern is to pass a serializer function through the default parameter.
Now json.dumps delegates unsupported objects to your function. This approach scales better when many payloads include datetimes.
Use a Custom JSON Encoder When You Need Central Control
If your application serializes datetimes in many places, a custom encoder can keep the behavior centralized.
This is useful when you want a consistent house rule for JSON encoding across a codebase.
Avoid the Temptation of default=str
You may see code like this:
It silences the error, but it is usually too broad. Any unsupported object will be converted with str, which can hide bugs and produce inconsistent formats.
For datetimes, an explicit serializer is better because it states exactly which types are supported and how they should appear in JSON.
Think About Deserialization Too
Serialization is only half the problem. Once a datetime is turned into JSON, it becomes a string. If the receiving side needs a datetime again, it must parse the string explicitly.
That is another reason ISO 8601 is a good default: Python can round-trip it cleanly and other systems can usually parse it too.
Prefer Timezone-Aware Values
Naive datetimes serialize, but they can create ambiguity about which timezone the timestamp represents. If the data crosses machine or service boundaries, use timezone-aware values when possible.
That avoids the common bug of serializing a local time that later gets interpreted as UTC or vice versa.
Common Pitfalls
- Passing raw
datetimeobjects tojson.dumpsand expecting the standard library to guess a format. - Converting some datetimes manually and forgetting others in larger payloads.
- Using
default=strand hiding unsupported-type bugs that should be handled explicitly. - Ignoring deserialization and then treating the JSON string as though it were still a
datetimeobject. - Using naive datetimes where timezone-aware timestamps are required.
Summary
- '
datetimeis not JSON serializable by default in Python’s standardjsonmodule.' - The usual fix is to convert it to a string, typically with
isoformat(). - The
defaulthook and custom encoders make the conversion reusable. - Avoid overly broad fallbacks such as
default=strunless that trade-off is intentional. - Timezone-aware datetimes produce safer JSON for distributed systems.

