How to Resolve "TypeError: Object of type datetime is not JSON serializable" in Python
When working with Python's json library, you may encounter the TypeError: Object of type datetime is not JSON serializable. This error occurs because the JSON data format has a limited set of supported data types (strings, numbers, booleans, lists, and dictionaries) and does not have a native equivalent for a datetime object.
To serialize a datetime object, you must first convert it into a string, which is a JSON-supported type. This guide will demonstrate the three most common and effective ways to handle this conversion, from a simple catch-all solution to more explicit formatting methods.
Understanding the Error: The JSON Data Type Limitation
The JSON (JavaScript Object Notation) standard is designed to be a simple, text-based data interchange format. It natively supports only the following data types:
- String:
"hello" - Number:
123,45.67 - Boolean:
true,false - Null:
null - Array:
[1, "a", true](a Pythonlist) - Object:
{"key": "value"}(a Pythondict)
Python's datetime object is not on this list. When json.dumps() encounters an object it doesn't know how to serialize, it raises a TypeError.
Reproducing the TypeError
The error is triggered when you try to serialize a dictionary (or other object) that contains a datetime object.
Example of code causing the error:
import json
from datetime import datetime
# A dictionary containing a non-serializable datetime object
data_to_serialize = {
'created_at': datetime.now(),
'user': 'Tom'
}
json_string = json.dumps(data_to_serialize)
Output:
Traceback (most recent call last):
File "main.py", line 10, in <module>
json_string = json.dumps(data_to_serialize)
File "/usr/lib/python3.8/json/__init__.py", line 231, in dumps
return _default_encoder.encode(obj)
File "/usr/lib/python3.8/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/lib/python3.8/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/usr/lib/python3.8/json/encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type datetime is not JSON serializable
Solution 1: Use the default Parameter in json.dumps()
The json.dumps() function has a convenient default parameter. You can pass it a function that will be called for any object that the JSON encoder doesn't know how to handle. This provides a clean, "catch-all" way to serialize datetime objects.
Solution:
import json
from datetime import datetime
data_to_serialize = {
'created_at': datetime.now(),
'user': 'Tom'
}
# The `default=str` argument tells dumps() to call str() on any non-serializable object.
json_string = json.dumps(data_to_serialize, default=str)
print(json_string)
Output:
{"created_at": "2025-11-16 14:38:02.691996", "user": "Tom"}
You can also pass a custom function to default. For example:
def my_converter(o):
if isinstance(o, datetime): return o.isoformat()
json.dumps(data, default=my_converter)
Solution 2: Convert to a Standard String Format (Best Practice)
For interoperability with other systems and APIs, it is a best practice to convert datetime objects to a standard, unambiguous string format like ISO 8601. The datetime.isoformat() method is perfect for this.
Solution:
import json
from datetime import datetime
now = datetime.now()
# Convert the datetime object to an ISO 8601 string before serializing
data_to_serialize = {
'created_at': now.isoformat(),
'user': 'Tom'
}
json_string = json.dumps(data_to_serialize)
print(f"Serialized with isoformat(): {json_string}")
# For custom formats, you can use .strftime()
custom_format_str = now.strftime("%Y-%m-%d %H:%M")
data_to_serialize_custom = {
'created_at': custom_format_str,
'user': 'Tom'
}
json_string_custom = json.dumps(data_to_serialize_custom)
print(f"Serialized with strftime(): {json_string_custom}")
Output:
Serialized with isoformat(): {"created_at": "2025-11-16T14:38:27.134519", "user": "Tom"}
Serialized with strftime(): {"created_at": "2025-11-16 14:38", "user": "Tom"}
Solution 3: Manually Convert with str()
A quick and simple fix is to manually wrap the datetime object with the str() function before passing it to json.dumps(). This is essentially what the default=str parameter does, but applied on a case-by-case basis.
Solution:
import json
from datetime import datetime
now = datetime.now()
# Manually convert the datetime object to a string
data_to_serialize = {
'created_at': str(now),
'user': 'Tom'
}
json_string = json.dumps(data_to_serialize)
print(json_string)
Output:
{"created_at": "2025-11-16 14:38:38.671466", "user": "Tom"}
Conclusion
| If you want to... | The best solution is... |
|---|---|
Handle all datetime objects in a single dumps call without changing the dictionary. | Use the default=str parameter in json.dumps(). |
| Ensure a standard, machine-readable format for APIs and data interchange. | Manually convert with .isoformat(). This is the recommended best practice. |
| Apply a custom date/time format. | Manually convert with .strftime(). |
| Make a quick, targeted fix. | Manually convert with str(). |
The TypeError: Object of type datetime is not JSON serializable is a straightforward problem to solve. By converting your datetime objects to a string format before serialization, you can easily bridge the gap between Python's data types and the JSON standard.