나는 이렇게 학습한다/Library

Pydantic 의 Datetime 타입으로 날짜와 시간을 다뤄보자

daco2020 2023. 8. 21. 13:27

Pydantic 의 네 가지 Datetime 타입

 

Pydantic은 데이터 유효성 검사와 데이터 클래스 설정을 간결하게 만들어주는 Python 라이브러리다. Pydantic에서는 날짜와 시간을 다루는 특별한 타입이 있는데, AwareDatetime, NaiveDatetime, PastDatetime, FutureDatetime이 바로 그것이다. 이 글을 통해 각각의 타입이 어떻게 동작하고 언제 사용되는지 확인해보자.

 

AwareDatetime

AwareDatetime은 시간대(timezone) 정보가 포함된 datetime 객체를 의미한다. 세계 각지의 시간대를 일관성 있게 처리해야 할 때 유용하게 쓸 수 있다.

사용 예시

from pydantic import BaseModel
from datetime import datetime
from zoneinfo import ZoneInfo
from pydantic import AwareDatetime


class Event(BaseModel):
    created_at: AwareDatetime

event = Event(created_at=datetime(2022, 8, 21, tzinfo=ZoneInfo('UTC')))
print(event.created_at)  # 2022-08-21 00:00:00+00:00

만약 시간대를 입력하지 않는다면 다음의 에러를 일으킨다.

pydantic_core._pydantic_core.ValidationError: 1 validation error for Event
created_at
  Input should have timezone info [type=timezone_aware, input_value=datetime.datetime(2022, 8, 21, 0, 0), input_type=datetime]
    For further information visit <https://errors.pydantic.dev/2.1/v/timezone_aware>

NaiveDatetime

NaiveDatetime은 시간대 정보가 없는 datetime 객체를 의미한다. 일반적인 날짜와 시간 처리에 쓸 수 있다.

사용 예시

from pydantic import NaiveDatetime


class Appointment(BaseModel):
    created_at: NaiveDatetime

appointment = Appointment(created_at=datetime(2022, 8, 21))
print(appointment.created_at)  # 2022-08-21 00:00:00

만약 시간대를 입력하면 다음의 에러를 일으킨다.

created_at
  Input should not have timezone info [type=timezone_naive, input_value=datetime.datetime(2022, 8...nfo.ZoneInfo(key='UTC')), input_type=datetime]
    For further information visit <https://errors.pydantic.dev/2.1/v/timezone_naive>

PastDatetime

PastDatetime은 현재 시각 이전의 datetime 객체를 의미하는 타입이다. 과거의 시간을 표현해야 할 때 유용하다.

사용 예시

from pydantic import PastDatetime


class HistoryEvent(BaseModel):
    happened_at: PastDatetime

history_event = HistoryEvent(happened_at=datetime(2000, 1, 1))
print(history_event.happened_at)  # 2000-01-01 00:00:00

 

FutureDatetime

FutureDatetime은 현재 시각 이후의 datetime 객체를 나타내는 타입이다. 미래의 일정이나 예정된 이벤트를 표현할 때 유용하다.

사용 예시

from pydantic import FutureDatetime


class FutureEvent(BaseModel):
    happening_at: FutureDatetime

future_event = FutureEvent(happening_at=datetime(2025, 1, 1))
print(future_event.happening_at)  # 2025-01-01 00:00:00

 

Pydantic의  PastDatetime, FutureDatetime 타입은 실제 유효성 검증도 가능하다. 

 

 


 

PastDatetime과 FutureDatetime의 유효성 검증

Pydantic의 PastDatetimeFutureDatetime은 특정 시간 값이 과거인지 미래인지를 자동으로 검증해주는데, 이 타입들을 어떻게 사용하고 왜 필요한지 살펴보자.

 

PastDatetime 실습코드

PastDatetime을 사용하기 위해 과거의 시간만 허용되는 필드를 만들 수 있다.

from datetime import timedelta


class HistoryEvent(BaseModel):
    happened_at: PastDatetime

# 현재 시각 이전의 시간을 입력
history_event = HistoryEvent(happened_at=datetime(2000, 1, 1, tzinfo=ZoneInfo('UTC')))
print(history_event.happened_at)  # 2000-01-01 00:00:00+00:00

# 현재 시각 이후의 시간을 입력하면 오류 발생!
future_time = datetime.now(tz=ZoneInfo('UTC')) + timedelta(days=1)
history_event = HistoryEvent(happened_at=future_time)  # 오류!
# 오류 메시지
pydantic_core._pydantic_core.ValidationError: 1 validation error for HistoryEvent
happened_at
  Input should be in the past [type=datetime_past, input_value=datetime.datetime(2023, 8...nfo.ZoneInfo(key='UTC')), input_type=datetime]
    For further information visit https://errors.pydantic.dev/2.1/v/datetime_past

 

FutureDatetime 실습코드

FutureDatetime는 반대로 미래의 시간만 허용되는 필드를 정의할 수 있다.

class FutureEvent(BaseModel):
    happening_at: FutureDatetime

# 현재 시각 이후의 시간을 입력
future_time = datetime.now(tz=ZoneInfo('UTC')) + timedelta(days=1)
future_event = FutureEvent(happening_at=future_time)
print(future_event.happening_at)  # 미래의 시간 출력

# 현재 시각 이전의 시간을 입력하면 오류 발생!
past_time = datetime(2000, 1, 1, tzinfo=ZoneInfo('UTC'))
future_event = FutureEvent(happening_at=past_time)  # 오류!
# 오류 메시지
pydantic_core._pydantic_core.ValidationError: 1 validation error for FutureEvent
happening_at
  Input should be in the future [type=datetime_future, input_value=datetime.datetime(2000, 1...nfo.ZoneInfo(key='UTC')), input_type=datetime]
    For further information visit https://errors.pydantic.dev/2.1/v/datetime_future

 

이처럼 PastDatetimeFutureDatetime을 사용하면 입력된 시간 값이 과거인지 미래인지에 대한 자동 유효성 검사를 수행할 수 있다. (참고로 이 둘은 시간대의 유무는 확인하지 않는다)

 

Pydantic 라이브러리를 활용하여 타입을 구분하면 데이터의 의미를 분명히 하고, 잘못된 입력을 방지하며, 코드의 가독성을 향상시킬 수 있다!