Sửa lỗi 'TypeError: Object of type datetime is not JSON serializable' trong Python

beginner🐍 Python2026-06-18| Python 3.8+, Linux, macOS, Windows

Error Message

TypeError: Object of type datetime is not JSON serializable
#python#json#datetime#serialization#json.dumps

Vấn đềViệc cố gắng xuất một dictionary trong Python thành một chuỗi JSON nhưng lại khiến chương trình bị treo là một trải nghiệm quen thuộc của các nhà phát triển. Bạn sử dụng phương thức tiêu chuẩn json.dumps(), nhưng thay vì nhận được một chuỗi sạch sẽ, bạn lại gặp một stack trace:

TypeError: Object of type datetime is not JSON serializable

Lỗi này thường xảy ra ngay khi bạn đang gửi dữ liệu tới một API hoặc lưu bản ghi vào đĩa. Bạn rất có thể sẽ gặp phải trở ngại này khi truy xuất các hàng từ PostgreSQL, MySQL hoặc MongoDB, nơi các cột timestamp tự động được chuyển đổi thành các đối tượng datetime của Python.

Mã ví dụ gây ra lỗi```

import json from datetime import datetime

data = { "id": 1024, "event": "User Signup", "timestamp": datetime.now() # Đối tượng này gây ra lỗi treo chương trình }

Dòng này sẽ gây ra lỗi TypeError

json_data = json.dumps(data)


## Tại sao điều này xảy raModule `json` tích hợp sẵn của Python hoạt động hiệu quả nhưng khá "khó tính". Theo mặc định, nó chỉ hiểu cách ánh xạ các kiểu dữ liệu cơ bản có tương đương trực tiếp trong JSON, chẳng hạn như chuỗi (string), số nguyên (integer), số thực (float) và kiểu logic (boolean). Bản thân JSON không có kiểu 'Date' gốc. Vì đặc tả không xác định ngày tháng nên là một chuỗi hay một con số, Python từ chối đoán thay bạn. Nó chỉ đơn giản là dừng quá trình lại.
## Cách khắc phục### Cách 1: Khắc phục nhanh (Sử dụng đối số 'default')Đối với các script nhỏ, hãy truyền một hàm vào tham số `default` trong `json.dumps()`. Điều này cho trình mã hóa biết phải làm gì khi gặp một đối tượng mà nó không nhận diện được.

import json from datetime import datetime

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

Ép kiểu bất kỳ đối tượng nào không thể tuần tự hóa thành chuỗi

json_data = json.dumps(data, default=str)

print(json_data)

Đầu ra: {"timestamp": "2024-06-17 14:30:05.123456"}


Mặc dù `default=str` rất nhanh, nhưng nó giống như một công cụ thô sơ. Bạn có thể thích một định dạng chuẩn hóa hơn như ISO 8601.
### Cách 2: Custom JSON Encoder (Khuyến nghị cho môi trường Production)Nếu bạn đang xây dựng một ứng dụng lớn hơn, một class encoder có thể tái sử dụng là lựa chọn tối ưu. Nó giữ cho logic tuần tự hóa (serialization) tập trung tại một nơi và đảm bảo tính nhất quán trong toàn bộ API của bạn.

import json from datetime import datetime, date

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

data = { "created_at": datetime.now(), "is_active": True }

Sử dụng đối số 'cls' để áp dụng logic tùy chỉnh của bạn

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

print(json_data)


### Cách 3: Tiền xử lý dữ liệuĐôi khi bạn không muốn thay đổi cách hoạt động của encoder. Thay vào đó, bạn có thể chuyển đổi dictionary một cách thủ công trước khi truyền nó vào hàm dump. Cách này thường an toàn hơn khi bạn chỉ có một hoặc hai trường ngày tháng.

from datetime import datetime import json

data = {"last_login": datetime.now()}

Tạo một bản sao nông (shallow copy) và định dạng trường cụ thể

clean_data = {**data, "last_login": data["last_login"].strftime('%Y-%m-%d %H:%M:%S')}

json_output = json.dumps(clean_data)


### Cách 4: Sử dụng Pydantic (Python hiện đại)Nếu bạn sử dụng FastAPI hoặc các công cụ kiểm định dữ liệu hiện đại, có thể bạn đã cài đặt **Pydantic**. Nó xử lý các trường hợp tuần tự hóa phức tạp một cách mặc định mà không cần cấu hình thêm.

from pydantic import BaseModel from datetime import datetime

class Event(BaseModel): name: str timestamp: datetime

event = Event(name="System Update", timestamp=datetime.now())

Pydantic v2 sử dụng model_dump_json()

print(event.model_dump_json())


## Các bước kiểm traSau khi áp dụng bản sửa lỗi, hãy chạy các bước kiểm tra sau để đảm bảo dữ liệu của bạn thực sự có thể sử dụng được:
- Xác nhận script kết thúc mà không gây ra lỗi `TypeError`.- Đảm bảo chuỗi ngày tháng ở đầu ra trông giống như `"2024-06-17T10:00:00"` thay vì một chuỗi đối tượng thô.- Xác minh JSON hợp lệ bằng cách thử tải ngược lại nó:```
try:
    json.loads(json_data)
    print("JSON hợp lệ và sẵn sàng để sử dụng.")
except Exception as e:
    print(f"Kiểm tra thất bại: {e}")

Phòng ngừa và Mẹo nhỏ- Tiêu chuẩn hóa theo ISO 8601: Sử dụng obj.isoformat(). Đây là tiêu chuẩn công nghiệp mà JavaScript, React và các ứng dụng di động có thể phân tích cú pháp (parse) ngay lập tức.- Sử dụng UTC: Tránh các lỗi về múi giờ bằng cách sử dụng datetime.now(timezone.utc). Lưu ý rằng utcnow() đã bị loại bỏ kể từ Python 3.12.Khi tôi đang gỡ lỗi các cấu trúc JSON phức tạp có chứa các ngày tháng lồng nhau, tôi thường sử dụng JSON Formatter tại ToolCraft để đảm bảo cấu trúc chính xác. Nếu bạn đang làm việc với Unix timestamp thay vì chuỗi, Timestamp Converter của họ rất hữu ích để kiểm tra xem các con số của bạn có thực sự chỉ đúng ngày hay không. Cả hai công cụ này đều chạy hoàn toàn trong trình duyệt của bạn, điều này rất tốt cho quyền riêng tư.

Related Error Notes