Подтвердить что ты не робот

Неожиданные результаты, преобразующие таймеры в python

Я пытаюсь понять, почему я получаю эти результаты при преобразовании часовых поясов в UTC:

In [74]: d1 = datetime(2007, 12, 5, 6, 30,tzinfo=pytz.timezone('US/Pacific'))
In [75]: d1
Out[75]: datetime.datetime(2007, 12, 5, 6, 30, tzinfo=<DstTzInfo 'US/Pacific' LMT-1 day, **16:07:00 STD**>)
In [76]: d1.astimezone(pytz.utc)
Out[76]: datetime.datetime(2007, 12, 5, 14, 23, tzinfo=<UTC>)

Почему 6:30 утра стали 2:23 вечера?

С другой стороны, если я использую следующий подход, я получаю ожидаемый результат:

In [90]: d2 = datetime(2007, 12, 5, 6, 30)
In [91]: uspac = pytz.timezone('US/Pacific')
In [92]: d2_aware = uspac.localize(d2)
In [94]: d2_aware.astimezone(pytz.utc)
Out[94]: datetime.datetime(2007, 12, 5, 14, 30, tzinfo=<UTC>)
4b9b3361

Ответ 1

Из частичной документации: http://pytz.sourceforge.net/#localized-times-and-date-arithmetic

К сожалению, использование аргумента tzinfo стандартных конструкторов datetime не работает с pytz для многих часовых поясов. [...] Это безопасно для часовых поясов без перехода на летнее время, хотя, например, в формате UTC. [...] Предпочтительный способ борьбы со временем - всегда работать в UTC, конвертируя его в локальное время только при генерации вывода для чтения людьми.

Ответ 2

То, что у меня есть, - это просто обходное решение, простое правило Никогда не создавайте datetime с информацией о часовом поясе, используя datetime().

Этот образец даст вам подсказку. Как вы видите, вы могли бы избежать неожиданной разницы, раз и только вы делаете "наивное" время и время (это, время и время без информации о часовом поясе), а затем локализуете его (оно не применяется при создании даты и времени в UTC, хотя):

import pytz
from datetime import datetime

# make Jan 1 on PDT -> UTC
pdt = pytz.timezone("America/Los_Angeles")
pdtnow1 = datetime(2014,1,1, tzinfo=pdt)
pdtnow2 = pdt.localize(datetime(2014,1,1))
pytz.utc.normalize(pdtnow1)
# > datetime.datetime(2014, 1, 1, 7, 53, tzinfo=<UTC>)
pytz.utc.normalize(pdtnow2)
# > datetime.datetime(2014, 1, 1, 8, 0, tzinfo=<UTC>)

# make Jan 1 on UTC -> PDT
utcnow1 = datetime(2014,1,1, tzinfo=pytz.utc)
utcnow2 = pytz.utc.localize(datetime(2014,1,1))
pdt.normalize(utcnow1)
# > datetime.datetime(2013, 12, 31, 16, 0, 
# > tzinfo=<DstTzInfo 'America/Los_Angeles' PST-1 day, 16:00:00 STD>)
pdt.normalize(utcnow2)
# > datetime.datetime(2013, 12, 31, 16, 0, 
# > tzinfo=<DstTzInfo 'America/Los_Angeles' PST-1 day, 16:00:00 STD>)

Ответ 3

Я пересматриваю некоторые вопросы о дате и времени, чтобы узнать, станут ли некоторые из более новых библиотек более полезными в таких ситуациях (или нет). pendulum - это тот, который хранит часовой пояс с датой и временем, что делает его особенно ценным в таких ситуациях.

>>> import pendulum
>>> d1 = pendulum.datetime(2007,12,5,6,30, tzinfo='US/Pacific')
>>> d1
<Pendulum [2007-12-05T06:30:00-08:00]>
>>> d1.timezone
<Timezone [US/Pacific]>
>>> d1.astimezone(tz='UTC')
<Pendulum [2007-12-05T14:30:00+00:00]>

Множество других сладких функций тоже.

Ответ 4

Распечатайте d2_aware до .astimezone, и вы увидите PST-1 (Стандартное тихоокеанское время), но в первом примере у вас есть LMT-1 (Local Mean Time) - и, вероятно, это может дать разницу в 7 минут.

Но я не знаю, почему pytz используют разные часовые пояса.