You are here because you received a TypeError: Object of type datetime is not JSON serializable
when you try to convert Python DateTime into JSON. In this article, we will see how to serialize DateTime instance into JSON. Also, decode back it to DateTime instance when we are reading JSON data. There are various ways to achieve this. You can pick the way you find it more useful for your problem.
Further Reading:
- Solve Python JSON Exercise to practice Python JSON skills

Subclass JSONEncoder to serialize DateTime into JSON
Python json module provides a json.JSONEncoder
Class. We can extend it If we want more customized output. i.e., To serialize the DateTime instance into JSON, we need to subclass JSONEncoder so we can implement our custom serialization.
When we say subclass json.JSONEncoder
that means we need to override the default()
method of a JSONEncoder Class, where we can convert DateTime value into ISO format so it can be serialized. ISO format produces a serialized version of datetime
.
As per ISO 8601, It converts DateTime in YYYY-MM-DDTHH:MM:SS
format, which is easy to encode and decode. we can use a isoformat()
method to convert DateTime value into ISO format.
The json.dump() and json.dumps() method of the JSON module has a cls
kwarg. Using this argument, you can pass a custom JSON Encoder, which tells json.dump()
or json.dumps()
method how to encode your DateTime into JSON formatted data.
I have an employee dict
, which contains employee details and his/her joining date. Let’s see how to encode employee details into JSON.
Now, let’s see the example.
import json
import datetime
from json import JSONEncoder
employee = {
"id": 456,
"name": "William Smith",
"salary": 8000,
"joindate": datetime.datetime.now()
}
# subclass JSONEncoder
class DateTimeEncoder(JSONEncoder):
#Override the default method
def default(self, obj):
if isinstance(obj, (datetime.date, datetime.datetime)):
return obj.isoformat()
print("Printing to check how it will look like")
print(DateTimeEncoder().encode(employee))
print("Encode DateTime Object into JSON using custom JSONEncoder")
employeeJSONData = json.dumps(employee, indent=4, cls=DateTimeEncoder)
print(employeeJSONData)
Output:
Printing to check how it will look like {"id": 456, "name": "William Smith", "salary": 8000, "joindate": "2020-01-08T18:52:50.637635"} Encode DateTime Object into JSON using custom JSONEncoder { "id": 456, "name": "William Smith", "salary": 8000, "joindate": "2020-01-08T18:52:50.637635" }
Deserialization of a dateTime in Python
Also, at the time of parsing JSON from file or string, we need to convert isoformat()
string back into a dateTime
object.
The object_hook
parameter of a json.load()
or json.loads()
method is used to define the custom JSON decoder. The object_hook
is the optional function that will be called with the result of any object literal decoded.
The Python built-in json module can only handle Python primitives types that have a direct JSON equivalent (e.g., dictionary, lists, strings, Numbers, None, etc.).
But when you want to convert JSON data into a custom Python type, we need to implement our custom decoder function and pass it as object_hook
to load() method so we can get custom Python type in return.
In our custom method, we need to convert a dateTime
string into a Python dateTime
object using the python-dateutil
module. Install it using pip install python-dateutil
. Let’s see the example now.
import json
import dateutil.parser
# custom Decoder
def DecodeDateTime(empDict):
if 'joindate' in empDict:
empDict["joindate"] = dateutil.parser.parse(empDict["joindate"])
return empDict
jsonData = """{"id": 456, "name": "William Smith", "saley": 8000, "joindate": "2020-01-08T15:29:52.040435"}"""
# use of object_hook
decodedJSON = json.loads(jsonData, object_hook=DecodeDateTime)
print(decodedJSON)
Output:
{'id': 456, 'name': 'William Smith', 'saley': 8000, 'joindate': datetime.datetime(2020, 1, 8, 15, 29, 52, 40435)}
Note: If you are using Python 3.7+, then you don’t need to use the python-dateutil
module. Instead, you can do conversion directly like this.
newdate = datetime.fromisoformat('2020-01-08T15:29:52.040435')
Serialize datetime by converting it into String
You can convert dateTime
value into its String representation and encode it directly, here you don’t need to write any encoder. We need to set the default parameter of a json.dump()
or json.dumps()
to str like this json.dumps(obj, default=str)
.
Let’s see the example.
import json
import datetime
employee = {
"id": 456,
"name": "William Smith",
"salary": 8000,
"joindate": datetime.datetime.now()
}
print("JSON Data")
print(json.dumps(employee, default=str))
Output:
JSON Data {"id": 456, "name": "William Smith", "salary": 8000, "joindate": "2020-01-08 18:39:30.161488"}
Write a custom method to serialize datetime into JSON
Instead of subclassing JSONEncoder
, we can create a custom method that will convert dateTime
into JSON.
The default
parameter of a json.dump()
or json.dumps()
method is used to override the behavior of a Python JSONEncoder. We need to create a custom method and pass it to the default
parameter of a json.dump()
or json.dumps()
method
import json
import datetime
employee = {
"id": 456,
"name": "William Smith",
"saley": 8000,
"joindate": datetime.datetime.now()
}
def default(obj):
if isinstance(obj, (datetime.date, datetime.datetime)):
return obj.isoformat()
print("Employee JSON Data")
print(json.dumps(employee, default=default))
Output:
Employee JSON Data {"id": 456, "name": "William Smith", "saley": 8000, "joindate": "2020-01-08T15:29:52.040435"}
Using a DjangoJSONEncoder
If you are using a Django you can take the advantage of native DjangoJSONEncoder serializer to serialize dateTime
.
import json
import datetime
from django.core.serializers.json import DjangoJSONEncoder
employee = {
"id": 456,
"name": "William Smith",
"saley": 8000,
"joindate": datetime.datetime.now()
}
print("JSON Data")
print(json.dumps(employee, cls=DjangoJSONEncoder))
Use Bson module to serialize and Dserialize dateTime to and from JSON
The bson
module has json_util class, which we can use directly to serialize and dateTime
into JSON without doing any explicit conversion.
Let see the example.
import json
import datetime
from bson import json_util
employee = {
"id": 456,
"name": "William Smith",
"salary": 8000,
"joindate": datetime.datetime.now()
}
jsonData = json.dumps(employee, default=json_util.default)
print(jsonData)
jsonData = """{"id": 456, "name": "William Smith", "saley": 8000, "joindate": "2020-01-08T15:29:52.040435"}"""
# Deserialization
decodedJson = json.loads(jsonData, object_hook=json_util.object_hook)