Last updated: Apr 8, 2024
Reading time·6 min

The Python "TypeError: Object of type datetime is not JSON serializable"
occurs when we try to convert a datetime object to a JSON string.
To solve the error, set the default keyword argument to str in your call
to the json.dumps() method.
Here is an example of how the error occurs.
import json from datetime import datetime now = datetime.now() # ⛔️ TypeError: Object of type datetime is not JSON serializable json_str = json.dumps({'created_at': now}, default=str)
We tried passing a datetime object to the json.dumps() method but the method
doesn't handle datetime objects by default.
default keyword argument to solve the errorTo solve the error, pass the default keyword argument setting it to the str
class.
import json from datetime import datetime now = datetime.now() # ✅ set default=str json_str = json.dumps({'created_at': now}, default=str) print(json_str) # 👉️ '{"created_at": "2023-07-19 17:42:13.501631"}' print(type(json_str)) # 👉️ <class 'str'>

The json.dumps method converts a Python object to a JSON formatted string.
default keyword argument can be set to a function that gets called for objects that can't otherwise be serialized.We simply convert the datetime object to a string by passing it to the str
class.
You can also define a custom JSON serializer function that takes care of converting dates to JSON.
from datetime import date, datetime import json def json_serializer(obj): if isinstance(obj, (datetime, date)): return obj.isoformat() raise TypeError(f'Type {type(obj)} is not serializable') now = datetime.now() json_str = json.dumps({'created_at': now}, default=json_serializer) # 👇️ {"created_at": "2023-07-19T17:43:33.333829"} print(json_str)

Notice that we set the default keyword argument to the json_serializer
function and not the str class.
The function
checks if the supplied value is a datetime
or date object and if the condition is met, it uses the
date.toisoformat()
method to return a string representing the date and time in ISO 8601 format.
from datetime import datetime now = datetime.now() # 👇️ 2023-02-09T09:14:19.515138 print(now.isoformat())
If the value that was passed to the function is not a date object, a TypeError
is raised.
DTEncoder class to solve the errorAn alternative approach is to extend from the JSONEncoder class and do the
conversion only for datetime objects.
import json from datetime import datetime class DTEncoder(json.JSONEncoder): def default(self, obj): # 👇️ If passed in object is `datetime` object # convert it to a string if isinstance(obj, datetime): return str(obj) # 👇️ otherwise use the default behavior return json.JSONEncoder.default(self, obj) now = datetime.now() json_str = json.dumps({'created_at': now}, cls=DTEncoder) print(json_str) # 👉️ '{"created_at": "2023-07-19 17:45:53.025469"}' print(type(json_str)) # 👉️ <class 'str'>

We extended from the JSONEncoder class.
The JSONEncoder class supports the following objects and types by default.
| Python | JSON |
|---|---|
| dict | object |
| list, tuple | array |
| str | string |
| int, float, int and float derived Enums | number |
| True | true |
| False | false |
| None | null |
Notice that the JSONEncoder class doesn't support datetime object to JSON
conversion by default.
We can handle this by extending from the class and implementing a default()
method that returns a serializable object.
import json from datetime import datetime class DTEncoder(json.JSONEncoder): def default(self, obj): # 👇️ If passed in object is datetime object # convert it to a string if isinstance(obj, datetime): return str(obj) # 👇️ otherwise use the default behavior return json.JSONEncoder.default(self, obj)
if statement, we check if the passed-in object is an instance of the datetime class and if it is, we convert it to a string and return the result.In all other cases, we let the base class's default method do the serialization.
To use a custom JSONEncoder, specify it with the cls keyword argument in
your call to the json.dumps() method.
# ✅ pass cls keyword argument json_str = json.dumps({'created_at': now}, cls=DTEncoder)
If you don't provide the cls kwarg, the default JSONEncoder is used.
strftime() method to solve the errorYou can also use the strftime method to convert a datetime object to a
string before converting it to JSON.
import datetime import json now = datetime.datetime.now() a_str = now.strftime('%Y-%m-%d %H:%M:%S') print(a_str) # 👉️ 2023-07-19 17:47:16 json_str = json.dumps(a_str) print(json_str) # 👉️ "2023-07-19 17:47:16"

The datetime class has a
strftime()
method which we can use to get a string representation of the date and time,
controlled by an explicit format string.
The code sample formats the datetime object as YYYY-MM-DD HH:MM:SS.
You can also include the milliseconds in the result.
import datetime import json now = datetime.datetime.now() a_str = now.strftime('%Y-%m-%d %H:%M:%S.%f') print(a_str) # 👉️ 2023-02-09 09:21:44.753545 json_str = json.dumps(a_str) print(json_str) # 👉️ "2023-02-09 09:21:44.753545"
If you want to format the datetime string in a different way, use
this table of the docs
to look up the format codes you should pass as the second argument to the
strftime() method.
str() class when convertingYou can also use the str() class when converting the value to JSON.
import json from datetime import datetime now = datetime.utcnow() json_str = json.dumps({'created_at': str(now)}) # 👇️ {"created_at": "2023-07-19 14:48:53.801604"} print(json_str)

Instead of relying on the default keyword argument, we explicitly convert the
date to a string using the str() class.
The Python "TypeError: Object of type Timestamp is not JSON serializable"
occurs when we try to convert a Timestamp object to a JSON string.
To solve the error, convert the Timestamp object to str before serializing
it to JSON.
Here is an example of how the error occurs.
import json import pandas as pd tstamp = pd.Timestamp('2023-01-01T12') # ⛔️ TypeError: Object of type Timestamp is not JSON serializable json_str = json.dumps({'created_at': tstamp})
We tried passing a Timestamp object to the json.dumps() method but the
method doesn't handle Timestamp objects by default
Timestamp to a str to solve the errorTo solve the error, use the built-in str() class to convert the Timestamp to
str before serializing it.
import json import pandas as pd tstamp = pd.Timestamp('2023-01-01T12') # ✅ convert to str json_str = json.dumps({'created_at': str(tstamp)}) print(json_str) # 👉️ '{"created_at": "2023-01-01 12:00:00"} print(type(json_str)) # 👉️ <class 'str'>
The default JSON encoder handles str values, so we can use a native Python
str instead of a Timestamp when serializing to JSON.
The json.dumps() method converts a Python object to a JSON formatted string.
PdEncoder class to solve the errorAlternatively, you can extend from the JSONEncoder class and handle the
conversions in a default method.
import json import pandas as pd class PdEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, pd.Timestamp): return str(obj) return json.JSONEncoder.default(self, obj) tstamp = pd.Timestamp('2023-01-01T12') json_str = json.dumps({'created_at': tstamp}, cls=PdEncoder) print(json_str) # 👉️ '{"created_at": "2023-01-01 12:00:00"} print(type(json_str)) # 👉️ <class 'str'>
We extended from the JSONEncoder class.
The JSONEncoder class supports the following objects and types by default.
| Python | JSON |
|---|---|
| dict | object |
| list, tuple | array |
| str | string |
| int, float, int and float derived Enums | number |
| True | true |
| False | false |
| None | null |
Notice that the JSONEncoder class doesn't support Timestamp to JSON
conversion by default.
We can handle this by extending from the class and implementing a default()
method that returns a serializable object.
import json import pandas as pd class PdEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, pd.Timestamp): return str(obj) return json.JSONEncoder.default(self, obj)
If the passed-in value is a Timestamp, we convert it to a str and return the
result.
The isinstance function returns
True if the passed-in object is an instance or a subclass of the passed-in
class.
To use a custom JSONEncoder, specify it with the cls keyword argument in
your call to the json.dumps() method.
import json import pandas as pd class PdEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, pd.Timestamp): return str(obj) return json.JSONEncoder.default(self, obj) tstamp = pd.Timestamp('2023-01-01T12') json_str = json.dumps({'created_at': tstamp}, cls=PdEncoder) print(json_str) # 👉️ '{"created_at": "2023-01-01 12:00:00"} print(type(json_str)) # 👉️ <class 'str'>
If you don't provide the cls kwarg, the default JSONEncoder is used.
I've also written an article on how to check if a variable is a Datetime object.
You can learn more about the related topics by checking out the following tutorials: