Home » 레퍼런스 » PYTHON » pytz localize 함수는 어떤 용도로 쓰는 함수일까요?

pytz localize 함수는 어떤 용도로 쓰는 함수일까요?

naive datetime에서 서울 시간대 정보를 정보를 얻어오기 위해, pytz의 localize를 사용해야 합니다. 왜 그럴까요? 그리고 pytz localize 함수가 무슨 역할을 하는지 이 글에서 간략하게 알아봅니다.


pytz의 _utcoffset

먼저, pytz.timezone(“Asia/Seoul”)을 호출하였을 때, 어떻게 동작하는지 간략하게 알아봅시다.

[그림 1] DstTzInfo의 __init__ 함수

“Asia/Seoul” timezone 정보를 불러오는 문장에 디버그를 걸어 봅시다. tzinfo.py의 DstTzInfo의 __init__ 함수에 멈추는 것을 볼 수 있습니다. 계속 디버그를 해 보면, else 문에 걸리는 것을 볼 수 있습니다.

여기서 중요한 것은 189번째 줄인데요. self._utcoffset입니다. 이 중요한 정보를 어디서 얻어오는가? 시간대의 _transition_info[0]에서 얻어옵니다.

[그림 2] 1번째 원소에 들어있는 정보

1번째 원소에 들어있는 정보를 보겠습니다. 8:28:00 이 들어와 있는데요. 이 정보가 self._utcoffset에 들어가게 됩니다. 여기까지 플로우를 정리해 봅시다.

Asia/Seoul의 시간대 정보는 1개보다 많이 있습니다. default로 가져오는 정보가 08:28:00입니다. 추측하건데, pytz쪽에서는 현재 시간 기반이 아니라 디폴트로 생각되는 정보를 가져왔을 겁니다. 생각해 보면, 호출하는 쪽에서 시간 정보를 넘겨준 적이 없습니다. 그러므로, 08:28:00을 _utcoffset에 세팅하는 것도 타당해 보입니다.


pytz localize 함수는 어떻게 동작하는가?

그러면 이 글에서 설명할 함수는 어떻게 naive datetime을 정확한 서울 시간으로 보정할까요?

[그림 3] dt를 인자로 받는 함수

해당 함수에 dt 정보가 들어오게 됩니다. naive datetime으로, 시간대 정보는 빠졌습니다. 하지만 최소한 시간 정보가 들어옵니다.

[그림 4] 알맞는 시간대 정보를 찾는 로직

이 함수에서는 self의 timezone 정보와 들어온 시간 정보를 이용하여, 이진 탐색 로직을 수행합니다. 이는, localize 함수에 들어온 시간 dt에 대응되는 올바른 시간대를 찾기 위함입니다. 예를 들어, dt가 2024년 4월 5일 오후 11시였다고 해 보겠습니다.

이 경우, 1988년 10월 8일 17시 0분 0시 이후의 시간대 정보인 29번째에 대응되는 _transition_info[29]를 얻어오게 됩니다. 왜 정확한 timezone 정보를 얻어왔을까요? 사실, pytz 입장에서는 별 문제가 없었습니다. 무슨 소리인가?

시간에 따라 시간대가 여러 번 변한 케이스인 경우 어떻게 처리해야 할까요? pytz 입장에서는 default 정보를 리턴하는 수밖에 없었을 겁니다. 지역에 대한 정보만 들어왔기 때문입니다. 시간 정보가 들어오면, 대응되는 올바른 timezone으로 바꿀 수 있었을 겁니다.

[그림 5] local time으로 바꾸는 로직

올바른 시간대 정보를 얻어오면, 올바른 local 시간대로 바꿀 수 있습니다.

  • dt.replace(tzinfo=tzinfo)
  • tzinfo.normalize

이 두 단계를 봅시다. 먼저, dt.replace는 시간대 정보만 kst +9:00:00으로 바꿉니다. 이 정보를 토대로, normalize를 합니다. 이 때 시간대 정보에 맞게 시간을 재조정 하게 됩니다.


예제 프로그램

그러면, 예제를 보도록 하겠습니다.

[그림 6] 예제 1의 앞부분

먼저, datetime에 서울 시간대 정보를 넣었습니다. 그리고, 이 정보를 가지고 utc 시간으로 바꾸었습니다. 이 경우 어떻게 동작할까요? datetime에 tzinfo에 서울 시간대를 넣으면, _utcoffset가 08:28:00로 나오게 됩니다. default 정보입니다.

[그림 7] astimezone 함수

함수 내부로 들어가 보시다. mytz에 datetime의 tzinfo를 씁니다. 공통적인 것은, mytz의 utcoffset를 호출한다는 점입니다.

[그림 8] default 정보를 가져오는 부분

여기서 사용하는 정보는 self._utcoffset입니다. 그런데 잘 보면, 기본적으로 pytz의 타임존은, _utcoffset에 디폴트 정보를 넣게 됩니다. 서울의 경우 08:28:00 이였습니다. 따라서, 이 정보가 들어가게 됩니다. datetime 정보에 상관 없이 말입니다.

[그림 9] 예제 1의 뒷부분

예제 1의 나머지 부분을 봅시다. 아까와는 다르게 seoul_tz를 localize 하였습니다. 이 경우, dt 정보인 1950년 3월 31일 12시에 맞게 시간대 정보가 들어가게 됩니다. 우연히도, 이 때에도 kst+9를 썼습니다. 실행 결과를 보겠습니다.

[그림 10] 예제 1의 실행 결과

실행 결과를 보면, 다르다는 것을 명확히 알 수 있습니다. 정리하면 아래와 같습니다.

  • pytz localize 함수는 지역정보만 주어지면 default 정보를 가져옵니다.
  • datetime은 시간대 정보를 저장합니다. 그런데 default 정보가 있네?
  • 고로, datetime의 시간과 pytz의 시간대 정보가 대응되지 않습니다.
  • 이를 맞추기 위해 localize로 보정해 주어야 합니다.

Leave a Comment

11 + 4 =