장고의 설정 파일에는 시간대(EX. 대한민국 시간대, UTC 세계 표준시 등)와 관련한 설정을 할 수 있는 대표적인 변수로서 TIME_ZONE과 USE_TZ가 존재한다. 이 값들을 어떻게 설정하느냐에 따라서 장고 서버 개발 시 datetime 객체를 사용하는 방법이 달라지므로 이에 대한 공부가 필요하다. 하나씩 차근차근 알아보자.
1. Default time zone VS Current time zone
① Default time zone : TIME_ZONE 변수로 지정한 시간대
② Current time zone : 템플릿 렌더링에 사용되는 시간대 (특별히 설정해주지 않으면 Default time zone과 동일)
※ 기본적으로 장고는 TIME_ZONE 설정 값으로 환경변수를 세팅하기 때문에, Default time zone이 기본적인 장고의 시간대로 사용된다. 이는 USE_TZ 설정 값과는 무관하다.
2. datetime 객체의 종류 (Naive VS Aware)
① Naive 객체 : tzinfo 속성이 설정되지 않은 datetime 객체 (TIME_ZONE 변수로 지정한 시간대 사용)
② Aware 객체 : tzinfo 속성이 설정된 datetime 객체 (명확하게 기준이 되는 시간대를 tzinfo 속성으로 지정)
3. USE_TZ 설정에 따른 차이
USE_TZ 변수의 값 | 특성 |
False | 장고는 내부적으로 Naive datetime 객체를 사용한다. 즉 장고 개발 시 Naive datetime 객체를 사용해야 한다. (기준 시간대는 항상 TIME_ZONE) |
True | 장고는 내부적으로 Aware datetime 객체를 사용한다. 즉 장고 개발 시 Aware datetime 객체를 사용해야 한다. (기준 시간대를 명확히 지정해줘야 함) 폼에 입력된 날짜 값은 Current time zone으로 해석한 뒤 Aware datetime 객체로 변환되고, 템플릿에 렌더링할 때는 Aware datetime 객체를 Current time zone으로 변환한다. ※ 만약 Naive datetime 객체를 사용하면 어떻게 될까? 하위호환성을 위해 Naive datetime 객체를 사용해도 문제가 없도록 설계가 되어 있다. 데이터베이스에 저장될 때 Naive datetime 객체를 Aware datetime 객체로 변환하고, 경고만 띄워준다. 하지만 그것도 DST 등으로 인한 문제가 발생할 여지는 있기 때문에, 항상 Aware datetime 객체를 사용하는 게 안전하다. |
4. 관련 라이브러리
① timezone.localtime() : 특정 시간대 기준 Aware 객체 → TIME_ZONE 시간대 기준의 Aware 객체 변환
② timezone.make_aware() : 시간대 기준이 없는 Naive 객체 → TIME_ZONE 시간대 기준의 Aware 객체 변환
from datetime import datetime, date, timedelta
from django.utils import timezone
import pytz
datetime.now() # Naive (TIME_ZONE)
datetime.now(pytz.UTC) # Aware (UTC)
timezone.now() # Aware (UTC)
timezone.localtime(datetime.now(pytz.UTC)) # Aware (UTC) → Aware (TIME_ZONE)
timezone.localtime(timezone.now()) # Aware (UTC) → Aware (TIME_ZONE)
timezone.make_aware(datetime.now()) # Naive (TIME_ZONE) → Aware (TIME_ZONE)
5. 상황 가정 (TIME_ZONE = 'Asia/Seoul', USE_TZ = True)
① datetime 객체를 사용할 땐 언제나 Aware 객체를 사용하자. timezone.now()가 권장된다.
② 그러면 DB에 저장되는 값도 UTC 기준 시간대로 저장되고, DB에서 값을 읽어올 때도 UTC 기준 시간대로 읽힌다.
③ 물론 템플릿에 렌더링 할 때는 알아서 한국 시간대로 변환이 되기 때문에 UTC라고 걱정할 필요는 없다.
④ 만약 UTC 기준 시간대의 Aware 객체를 한국 시간대의 Aware 객체로 변환하고 싶다면 timezone.localtime() 함수를 사용하자.
⑤ 참고로 DateField는 걱정하지 않고 사용해도 된다. 언제나 TIME_ZONE 기준 시간이 사용된다.
자세한 내용은 장고 공식 문서 참조.
https://docs.djangoproject.com/en/3.0/topics/i18n/timezones/
'장고 (Django)' 카테고리의 다른 글
[Django] REST framework - ① Serialization (10) | 2020.06.26 |
---|---|
[Django] REST API, Django REST framework (DRF) (4) | 2020.06.26 |
[Django] 프로젝트 구조 설정 (앱, 템플릿, Static 파일 등) (0) | 2020.06.01 |
[Django] 개발 환경 세팅 : CentOS7 (VirtualBox + Vagrant), PyCharm (0) | 2020.05.27 |
[Django] Filtering based on Aggregation (0) | 2020.04.02 |