如何在 Fast API 中将 unix 时间戳解析为没有时区的日期时间
How to parse unix timestamp into datetime without timezone in Fast API
假设我有一个 pydantic 模型
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_dt
和end_dt
都是unix时间戳。但在端点,它们变成了带时区的日期时间。
@app.put('...')
def edit_event(event_data: EventEditRequest):
event_data.start_dt.tzinfo is not None # True
我不想在端点函数中手动编辑 start_dt
和 end_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, 9, 18, 10, 32, 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)
就像 sashaaero 在他们的回答中提到的那样,您可以使用自定义类型来实现。但是,与其创建自己的验证,不如使用 Pydantic 中现有的验证器,然后删除时区信息。
from pydantic.datetime_parse import parse_datetime
class OffsetNaiveDatetime(datetime):
@classmethod
def __get_validators__(cls):
yield cls.validate
@classmethod
def validate(cls, v):
v = parse_datetime(v)
v = v.replace(tzinfo=None)
return v
但请注意仅在根本不需要或不适用时区信息的情况下使用它。
假设我有一个 pydantic 模型
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_dt
和end_dt
都是unix时间戳。但在端点,它们变成了带时区的日期时间。
@app.put('...')
def edit_event(event_data: EventEditRequest):
event_data.start_dt.tzinfo is not None # True
我不想在端点函数中手动编辑 start_dt
和 end_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, 9, 18, 10, 32, 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)
就像 sashaaero 在他们的回答中提到的那样,您可以使用自定义类型来实现。但是,与其创建自己的验证,不如使用 Pydantic 中现有的验证器,然后删除时区信息。
from pydantic.datetime_parse import parse_datetime
class OffsetNaiveDatetime(datetime):
@classmethod
def __get_validators__(cls):
yield cls.validate
@classmethod
def validate(cls, v):
v = parse_datetime(v)
v = v.replace(tzinfo=None)
return v
但请注意仅在根本不需要或不适用时区信息的情况下使用它。