How to change date format in pydantic

We Are Going To Discuss About How to change date format in pydantic. So lets Start this Python Article.

How to change date format in pydantic

  1. How to solve How to change date format in pydantic

    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.

  2. How to change date format in pydantic

    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.

Solution 1

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.

Original Author Fabian Of This Content

Solution 2

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"}

Original Author Omer Shacham Of This Content

Solution 3

In case you don’t necessarily want to apply this behavior to all datetimes, you can create a custom type extending datetime. For example, to make a custom type that always ensures we have a datetime with tzinfo set to UTC:

from datetime import datetime, timezone

from pydantic.datetime_parse import parse_datetime


class utc_datetime(datetime):
    @classmethod
    def __get_validators__(cls):
        yield parse_datetime  # default pydantic behavior
        yield cls.ensure_tzinfo

    @classmethod
    def ensure_tzinfo(cls, v):
        # if TZ isn't provided, we assume UTC, but you can do w/e you need
        if v.tzinfo is None:
            return v.replace(tzinfo=timezone.utc)
        # else we convert to utc
        return v.astimezone(timezone.utc)
    
    @staticmethod
    def to_str(dt:datetime) -> str:
        return dt.isoformat() # replace with w/e format you want

Then your pydantic models would look like:

from pydantic import BaseModel

class SomeObject(BaseModel):
    some_datetime_in_utc: utc_datetime

    class Config:
        json_encoders = {
            utc_datetime: utc_datetime.to_str
        }

Going this route helps with reusability and separation of concerns 🙂

Original Author aiguofer Of This Content

Conclusion

So This is all About This Tutorial. Hope This Tutorial Helped You. Thank You.

Also Read,

ittutorial team

I am an Information Technology Engineer. I have Completed my MCA And I have 4 Year Plus Experience, I am a web developer with knowledge of multiple back-end platforms Like PHP, Node.js, Python and frontend JavaScript frameworks Like Angular, React, and Vue.

Leave a Comment