Django timezone 문제 파헤치기
Python django 에서 날짜와 시간을 다룰 때 발생할 수 있는 timezone 문제를 겪으면서 알게된 점들을 공유해보려고 합니다. 이 포스팅은 python 3.5 django 1.9에 PostgreSQL 사용을 기준으로 합니다.
프로젝트 설정
한국 시간(UTC+9)을 사용하기 위해 django 프로젝트의 settings.py 에 아래와 같이 설정을 합니다.
USE_TZ = True
TIME_ZONE = 'Asia/Seoul'
설정에 따른 영향
- datetime.datetime.now() datetime.datetime.today() 등으로 현재 날짜/시간을 가져오는 경우 TIME_ZONE 설정에 따라 +9 기준의 값이 나오지만 TIME_ZONE 정보가 없는 naive datetime 객체입니다.
- 위의 시간값을 사용해서 DB 에 저장하면 UTC 기준 시간값으로 저장이 됩니다. (time-zone-aware datetime 객체)
- django 모델을 통해 DB 에서 읽은 DateTimeField 타입의 컬럼 값은 TIME_ZONE 이 UTC 인 time-zone-aware datetime 객체입니다.
문제가 발생할 수 있는 부분
- 위의 3번처럼 읽은 시간값에 .date() 를 호출해서 날짜만 얻으면 UTC 기준의 날짜가 나오므로 한국 시간 기준의 날짜와 맞지 않을 수 있습니다. 예를 들어 한국 시간으로 9시 이전이면 UTC 기준으로 하면 하루 전이 되어버립니다.
- string 을 datetime.datetime.strptime() 함수를 통해 날짜/시간값을 얻거나 datetime.datetime.now() 를 등을 통해 현재 날짜/시간값을 얻은 naive datetime 객체를 time-zone-aware datetime 객체와 비교시 exception 이 발생합니다.
- django 모델의 DateField 의 경우는 UTC 기준이 아닌 한국 날짜로 저장이 되고 읽어집니다.
문제 해결 방법
- naive datetime 개체인 datetime.datetime.now() 를 사용하는 대신 django.utils.timezone.now() 를 사용해서 time-zone-aware datetime 객체를 사용하도록 합니다.
-
한국 시간이 필요한 경우 아래와 같은 코드를 사용해서 변환합니다.
from django.utils import timezone now = timezone.localtime()
-
naive datetime 객체를 어쩔 수 없이 사용해야 하는 경우 아래와 같은 코드를 사용해서 time-zone-aware datetime 객체로 변환합니다.
from datetime import datetime from django.utils import timezone repay_datetime = datetime.strptime('2016-10-01 14:00:00', '%Y-%m-%d %H:%M:%S') repay_datetime_aware = timezone.make_aware(repay_datetime) if investment.created_datetime > repay_datetime_aware: do_something()
맺음말
한국 시간대에 맞는 한국향 서비스를 개발하게 되면 timezone 문제를 겪을 수 있습니다. 전세계의 기준 시간대가 한국 시간대면 좋겠지만 아닌게 현실이기 때문에 문제가 발생하지 않도록 잘 개발할 수 밖에 없는게 현실입니다. 한국의 많은 django 개발자들에게 도움이 되길 바라면서 글을 마칩니다.