How to Fix Python TypeError: object of type datetime is not JSON serializable

The TypeError: object of type datetime is not JSON serializable occurs because the datetime objects are not natively serializable to JSON. JSON serialization in Python, using libraries like json, can handle basic data types (e.g., strings, numbers, lists, and dictionaries), but not more complex types like datetime.

To fix this error, you need to convert datetime objects to a format that is JSON serializable. Here are several common approaches to solve this issue:

1. Convert datetime to String

You can convert datetime objects to strings before serializing them. One common format is ISO 8601.

import json
from datetime import datetime

def default_converter(o):
    if isinstance(o, datetime):
        return o.isoformat()
    raise TypeError(f"Object of type {o.__class__.__name__} is not JSON serializable")

data = {
    "name": "John",
    "timestamp": datetime.now()
}

json_data = json.dumps(data, default=default_converter)
print(json_data)

2. Use a Custom JSON Encoder

Another approach is to create a custom JSON encoder by subclassing json.JSONEncoder.

import json
from datetime import datetime

class DateTimeEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, datetime):
            return o.isoformat()
        return super().default(o)

data = {
    "name": "John",
    "timestamp": datetime.now()
}

json_data = json.dumps(data, cls=DateTimeEncoder)
print(json_data)

3. Convert datetime to Unix Timestamp

You can convert the datetime object to a Unix timestamp (the number of seconds since January 1, 1970).

import json
from datetime import datetime

def default_converter(o):
    if isinstance(o, datetime):
        return o.timestamp()
    raise TypeError(f"Object of type {o.__class__.__name__} is not JSON serializable")

data = {
    "name": "John",
    "timestamp": datetime.now()
}

json_data = json.dumps(data, default=default_converter)
print(json_data)

4. Use simplejson

The simplejson library can handle datetime objects natively. You need to install the library first using pip install simplejson.

import simplejson as json
from datetime import datetime

data = {
    "name": "John",
    "timestamp": datetime.now()
}

json_data = json.dumps(data, default=json.encoder.JSONEncoderForDatetime)
print(json_data)

This will output a JSON serialized string representation of the datetime object.

Example: Encoding and Decoding

When you decode the JSON data back into Python objects, you’ll need to handle the conversion of the string or timestamp back into a datetime object.

import json
from datetime import datetime

class DateTimeEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, datetime):
            return o.isoformat()
        return super().default(o)

def as_datetime(dct):
    for key, value in dct.items():
        try:
            dct[key] = datetime.fromisoformat(value)
        except (ValueError, TypeError):
            pass
    return dct

data = {
    "name": "John",
    "timestamp": datetime.now()
}

json_data = json.dumps(data, cls=DateTimeEncoder)
print("Serialized:", json_data)

decoded_data = json.loads(json_data, object_hook=as_datetime)
print("Deserialized:", decoded_data)

This will ensure your datetime objects are properly serialized to JSON and deserialized back to datetime objects.

Stephen Mclin
Stephen Mclin

Hey, I'm Steve; I write about Python and Django as if I'm teaching myself. CodingGear is sort of like my learning notes, but for all of us. Hope you'll love the content!

Articles: 90

Leave a Reply

Your email address will not be published. Required fields are marked *