Задача: разобраться, как нормально работать с временными зонами в Django/PostgreSQL.
Решение.
Включить в Django
Для работы со временем и датой всегда использовать
Дело в том, что
PostgreSQL в связке с Django по умолчанию хранит все временные метки timestamp в UTC временной зоне и при использовании ORM установленная в Django временная зона перегоняется в UTC и в базе хранится как UTC.
Использование
Решение.
Включить в Django
settings.py
использование временных зон и указать нужную зону:
USE_TZ=True
TIME_ZONE = 'Europe/Moscow'
Для работы со временем и датой всегда использовать
django.utils.timezone.localtime
:
from django.utils import timezone
now = timezone.localtime(timezone.now())
Дело в том, что
timezone.now()
отдает время в UTC метке и тут можно напороться на два не очень удобных момента: в 2 часа московской ночи timezone.now().date()
покажет неверную дату, и время timezone.now().hour
— не текущий час в Москве, а текущий час по UTC. Поэтому всегда используем timezone.localtime()
для получения нормального Московского времени. PostgreSQL в связке с Django по умолчанию хранит все временные метки timestamp в UTC временной зоне и при использовании ORM установленная в Django временная зона перегоняется в UTC и в базе хранится как UTC.
Использование
localtime()
прекрасно — в Python коде мы уверены, что это всегда именно локальное нормальное время и дата.