Ответ 1
В соответствии с Wikipedia переход к летнему времени и из него происходит в 01:00 UTC.
-
В 00:12 UTC вы все еще находитесь в центральноевропейском летнем времени (т.е. UTC + 02: 00), поэтому местное время 02:12.
-
В 01:12 UTC вы вернулись в стандартное центральноевропейское время (т.е. UTC + 01: 00), поэтому местное время снова 02:12.
При переходе с летнего времени на стандартное время местное время идет с 02:59 до 02:00, и час повторяется. Поэтому, когда вы спрашиваете о смещении UTC в 02:12 (местное время), ответ может быть правдивым либо +01: 00, либо +02: 00 - это зависит от версии 02:12, о которой вы говорите.
При дальнейшем изучении библиотеки pytz, я думаю, ваша проблема может заключаться в том, что вы не должны использовать реализацию pytz.reference, которая может не справиться с этими двусмысленностями очень хорошо. Цитата из комментариев в исходном коде:
Справочные реализации tzinfo из документов Python. Используется для тестирования, поскольку они верны только для лет С 1987 по 2006. Не используйте их для реального кода.
Работа с неоднозначными временами в pytz
Что вы должны делать, так это создание объекта часового пояса для соответствующего часового пояса:
import pytz
cet = pytz.timezone('CET')
Затем вы можете использовать метод utcoffset для вычисления смещения UTC даты/времени в этом часовом поясе.
dt = datetime.datetime(2010, 10, 31, 2, 12, 30)
offset = cet.utcoffset(dt)
Обратите внимание, что приведенный выше пример будет вызывать исключение AmbiguousTimeError, потому что он не может определить, какую из двух версий 02:12:30 вы имели в виду. К счастью, pytz позволит вам указать, хотите ли вы версию dst или стандартную версию, установив параметр is_dst. Например:
offset = cet.utcoffset(dt, is_dst = True)
Обратите внимание, что это не вредно для установки этого параметра во всех вызовах utcoffset, даже если время не будет неоднозначным. Согласно документации, он используется только во время переходных периодов перехода DST для устранения этой двусмысленности.
Как работать со отметками времени
Что касается обработки временных меток, лучше всего хранить их как значения UTC как можно дольше, иначе вы можете в конечном итоге выбросить ценную информацию. Поэтому сначала конвертируйте в datetime UTC с помощью метода datetime.utcfromtimestamp.
dt = datetime.datetime.utcfromtimestamp(1288483950)
Затем используйте pytz для локализации времени как UTC, поэтому часовой пояс привязан к объекту datetime.
dt = pytz.utc.localize(dt)
Наконец, вы можете конвертировать этот UTC datetime в свой часовой пояс и получить смещение временной зоны следующим образом:
offset = dt.astimezone(cet).utcoffset()
Обратите внимание, что этот набор вычислений приведет к правильным смещениям для 1288483950 и 1288487550, хотя обе отметки времени представлены в 02:12:30 в часовом поясе CET.
Определение локального часового пояса
Если вам нужно использовать локальный часовой пояс своего компьютера, а не фиксированный часовой пояс, вы не можете сделать это напрямую из pytz. Вы также не можете просто создать объект pytz.timezone, используя имя часового пояса от time.tzname, потому что имена не всегда будут распознаны pytz.
Решение заключается в использовании tzlocal module - его единственная цель - предоставить эту недостающую функциональность в pytz. Вы используете его следующим образом:
import tzlocal
local_tz = tzlocal.get_localzone()
Функция get_localzone() возвращает объект pytz.timezone, поэтому вы должны иметь возможность использовать это значение во всех местах, где я использовал переменную cet в приведенных выше примерах.