如何在Fast API中将Unix时间戳解析为不带时区的日期时间

问题描述

假设我有一个pytantic模型

class EventEditRequest(BaseModel):
    uid: UUID
    name: str
    start_dt: datetime
    end_dt: datetime

我以正文b'{"uid":"a38a7543-20ca-4a50-ab4e-e6a3ae379d3c","name":"test event2222","start_dt":1600414328,"end_dt":1600450327}'发送请求

因此start_dtend_dt都是unix时间戳。但是在端点中,它们变成带有时区的日期时间。

@app.put('...')
def edit_event(event_data: EventEditRequest):
    event_data.start_dt.tzinfo is not None  # True

我不想在终结点函数中手动编辑start_dtend_dt来摆脱时区。如何设置我的Pydantic模型,这样它将使日期时间不带有时区?

解决方法

您可以使用自己的@validator来手动解析datetime

from datetime import datetime

from pydantic import BaseModel,validator


class Model(BaseModel):
    dt: datetime = None


class ModelNaiveDt(BaseModel):
    dt: datetime = None

    @validator("dt",pre=True)
    def dt_validate(cls,dt):
        return datetime.fromtimestamp(dt)


print(Model(dt=1600414328))
print(ModelNaiveDt(dt=1600414328))

输出:

dt=datetime.datetime(2020,9,18,7,32,8,tzinfo=datetime.timezone.utc)
dt=datetime.datetime(2020,10,8)
,

另一种实现方法是创建自定义类型

class UnixDatetime(datetime):
    @classmethod
    def __get_validators__(cls):
        yield cls.validate

    @classmethod
    def validate(cls,v):
        if isinstance(v,datetime):
            print('Some request sends datetime not in UNIX format',file=sys.stderr)
            return v.replace(tzinfo=None)
        elif isinstance(v,int):
            return datetime.fromtimestamp(v)
        assert False,'Datetime came of %s type' % type(v)