Digging into Django's timezone problem
Key point
In Django, mixing naive datetime and aware datetime causes timezone issues in date storage and comparison.
Details
This summarizes the timezone problems encountered while handling dates and times in a Python 3.5, Django 1.9, and PostgreSQL environment.
Even with USE_TZ = True and TIME_ZONE = 'Asia/Seoul' set, datetime.datetime.now() or datetime.datetime.today() returns a naive datetime. On the other hand, DateTimeField values read and saved through a Django model become UTC-based time-zone-aware datetime, so even if they look like the same time, their internal representation can differ.
This difference causes the following problems.
- Calling
.date()on aDateTimeFieldvalue read from the DB gives the UTC date. - Even if it's the same day in Korean time, it may become the previous day in UTC if it's before 9 AM.
- Directly comparing a naive datetime created with
strptime()to an aware datetime raises an exception. - Unlike
DateTimeField,DateFieldis stored and read based on Korean date.
The solution is clear. When the current time is needed, use django.utils.timezone.now() instead of datetime.datetime.now() to get an aware datetime. When conversion to Korean time is needed, use timezone.localtime().
If you have no choice but to receive a naive datetime, you must convert it to an aware datetime using timezone.make_aware() before comparing.
Ultimately, when building a service for the Korean timezone, you must always be aware that "the time you see" and "the time that gets stored and compared" can differ, and the key is not to mix in naive datetime.
This summary was generated automatically by AI. Check the original for the author's claims and context. Copyright belongs to the original author.
Our guide explains how the AI works. Report summary errors, attribution issues, or removal requests via Contact.