Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change date format in pydantic

How to change date format in pydantic for validation and serialization? For validation I am using @validator. Is there an solution for both cases?

like image 578
jonsbox Avatar asked Mar 02 '23 17:03

jonsbox


2 Answers

You can implement a custom json serializer by using pydantic's custom json encoders. Then, together with pydantic's custom validator, you can have both functionalities.


from datetime import datetime, timezone
from pydantic import BaseModel, validator


def convert_datetime_to_iso_8601_with_z_suffix(dt: datetime) -> str:
    return dt.strftime('%Y-%m-%dT%H:%M:%SZ')


def transform_to_utc_datetime(dt: datetime) -> datetime:
    return dt.astimezone(tz=timezone.utc)


class DateTimeSpecial(BaseModel):
    datetime_in_utc_with_z_suffix: datetime

    # custom input conversion for that field
    _normalize_datetimes = validator(
        "datetime_in_utc_with_z_suffix",
        allow_reuse=True)(transform_to_utc_datetime)

    class Config:
        json_encoders = {
            # custom output conversion for datetime
            datetime: convert_datetime_to_iso_8601_with_z_suffix
        }


if __name__ == "__main__":
    special_datetime = DateTimeSpecial(datetime_in_utc_with_z_suffix="2042-3-15T12:45+01:00")  # note the different timezone

    # input conversion
    print(special_datetime.datetime_in_utc_with_z_suffix)  # 2042-03-15 11:45:00+00:00

    # output conversion
    print(special_datetime.json())  # {"datetime_in_utc_with_z_suffix": "2042-03-15T11:45:00Z"}

This variant also works in fastapi's serializer where I am actually using it in that way.

like image 163
Fabian Avatar answered Mar 06 '23 20:03

Fabian


I think that pre validator can help here.

from datetime import datetime, date

from pydantic import BaseModel, validator


class OddDate(BaseModel):
    birthdate: date

    @validator("birthdate", pre=True)
    def parse_birthdate(cls, value):
        return datetime.strptime(
            value,
            "%d/%m/%Y"
        ).date()


if __name__ == "__main__":
    odd_date = OddDate(birthdate="12/04/1992")
    print(odd_date.json()) #{"birthdate": "1992-04-12"}
like image 41
Omer Shacham Avatar answered Mar 06 '23 19:03

Omer Shacham