안녕하세요. IT 엘도라도 에 오신 것을 환영합니다.
글을 쓰는 것은 귀찮지만 다시 찾아보는 것은 더 귀찮습니다.
완전한 나만의 것으로 만들기 위해 지식을 차곡차곡 저장해 보아요.   포스팅 둘러보기 ▼

장고 (Django)

[Django] TIME_ZONE, USE_TZ 설정

피그브라더 2020. 1. 11. 21:56

장고의 설정 파일에는 시간대(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/

 

Time zones | Django documentation | Django

Django The web framework for perfectionists with deadlines. Overview Download Documentation News Community Code Issues About ♥ Donate

docs.djangoproject.com