如何在Pydantic的datetime字段中指定本地时区?[Python]
解决方法
方案一:通过Pydantic序列化时转换时区
首先修正你Pydantic模型中的json_encoders错误(isoformat是方法,需要调用),同时添加时区转换逻辑,将数据库返回的UTC时间转为本地时区:
from zoneinfo import ZoneInfo # Python 3.9+ 可用,低版本可替换为 pytz from datetime import datetime from bson.objectid import ObjectId from pydantic import BaseModel, Field class DamBaseModel(BaseModel): class Config: allow_population_by_field_name = True use_enum_values = True arbitrary_types_allowed = True json_encoders = { ObjectId: str, # 转换为指定本地时区(示例为上海时区)后生成ISO格式字符串 datetime: lambda d: d.astimezone(ZoneInfo("Asia/Shanghai")).isoformat() } class Message(DamBaseModel): created_datetime: datetime = Field(default_factory=datetime.now)
之后确保从MongoDB取出的数据经过Pydantic模型序列化:
# 假设从数据库取出原始数据 raw_data = collection.find_one({"_id": your_object_id}) # 用Pydantic模型解析并序列化 message = Message(**raw_data) client_response = message.model_dump_json()
方案二:MongoDB聚合查询时直接转换时区
如果不想在Python端处理,可通过MongoDB的聚合管道$dateToString操作符,在投影阶段直接将UTC时间转为指定时区的字符串:
from pymongo import MongoClient client = MongoClient("your_mongo_uri") db = client.your_database collection = db.your_collection # 聚合管道:投影时转换时区(示例为上海时区) pipeline = [ { "$project": { "created_datetime": { "$dateToString": { "format": "%Y-%m-%dT%H:%M:%S%z", # ISO格式 "date": "$created_datetime", "timezone": "Asia/Shanghai" # 替换为你的目标时区 } } } } ] # 执行聚合查询 results = list(collection.aggregate(pipeline))
返回的results中created_datetime就是转换后时区的ISO格式字符串,可直接返回给客户端。
补充说明
你当前客户端收到的"Mon, 22 Aug 2022 12:02:59 GMT"是Python默认的datetime对象字符串格式(RFC 1123),原因是你直接返回了数据库查询得到的datetime对象,没有经过Pydantic模型的自定义序列化逻辑。只要确保数据经过Pydantic处理,或在MongoDB查询时转换格式,就能得到时区正确的结果。
内容的提问来源于stack exchange,提问作者SrTan
相关产品推荐
相关产品推荐

