Я использую django 1.11 и pytz 2018.6
У меня возникают проблемы с пониманием того, как django работает с DST.
Моя главная проблема - локализация даты 2018-11-04 00:00:00
вAmerica/Sao_Paulo
часовой пояс.Согласно последней версии pytz, это дата, когда DST запускается в этом часовом поясе в 2018 году.
Что ж, в моем приложении я увидел исключение pytz.exceptions.NonExistentTimeError
при попытке локализовать указанную дату.Следующий код воспроизводит это исключение:
import os
import datetime
import django
import pytz
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings")
django.setup()
from django.utils.timezone import make_aware
sp = pytz.timezone('America/Sao_Paulo')
dst_start_date = datetime.datetime(2018, 11, 4, 0, 0, 0)
make_aware(dst_start_date, sp)
# Exception raised: pytz.exceptions.NonExistentTimeError: 2018-11-04 00:00:00
Однако, если я пытаюсь локализовать, используя pytz.localize
вместо make_aware
, я получаю другие результаты:
sp.localize(dst_start_date) # Returns 2018-11-04 00:00:00-03:00
Я ожидал получитьэто же исключение при попытке локализации.Но это не вызвало исключения и фактически вернуло неправильный результат (смещение -03:00
происходит, когда мы не на летнем времени. В конкретную дату я ожидал, что дата 2018-11-04 00:00:00-03:00
будет конвертирована в 2018-11-04 00:00:00-02:00
).
Это смущает меня, потому что при чтении кода make_aware
в django.utils.timezone
я понял, что вызывается один и тот же метод pytz.tzinfo.localize
.
# django.utils.timezone
def make_aware(value, timezone=None, is_dst=None):
"""
Makes a naive datetime.datetime in a given time zone aware.
"""
if timezone is None:
timezone = get_current_timezone()
if hasattr(timezone, 'localize'):
# This method is available for pytz time zones.
return timezone.localize(value, is_dst=is_dst)
else:
# Check that we won't overwrite the timezone of an aware datetime.
if is_aware(value):
raise ValueError(
"make_aware expects a naive datetime, got %s" % value)
# This may be wrong around DST changes!
return value.replace(tzinfo=timezone)
Почему оба результата различны?Почему я не получаю исключение при попытке вручную локализовать дату от 2018-11-04 00:00:00
до America/Sao_Paulo
?
Пожалуйста, убедитесь, что у вас установлена последняя версия pytz (pip install pytz --upgrade
), прежде чем пытаться использовать этот код, потому что мы имелиизменение даты перехода на летнее время в этом году.