На этом шаге мы рассмотрим основные принципы работы с временными зонами.
У вас назначена телефонная конференция на 21 декабря 2012 года в 9:30 утра в Чикаго. В какое местное время ваш друг из индийского города Бангалор должен выйти на связь?
Для практически любых задач, связанных с временными зонами, вы можете использовать модуль pytz.
https://pypi.org/project/pytz/.
Этот пакет предоставляет базу временных зон Олсона (tz databaze), которая является стандартом де-факто для многих языков программирования и операционных систем.
Большая часть случаев использования pytz приходится на приведение к локальному времени дат, созданных с помощью библиотеки datetime. Например, вот как вы могли бы представить дату с чикагским местным временем:
>>> from datetime import datetime >>> from pytz import timezone >>> d = datetime(2012, 12, 21, 9, 30, 0) >>> print(d) 2012-12-21 09:30:00 >>>
>>> # Локализуем дату для Чикаго >>> central = timezone('US/Central') >>> loc_d = central.localize(d) >>> print(loc_d) 2012-12-21 09:30:00-06:00 >>>
Когда дата локализована, ее можно конвертировать в другие временные зоны. Чтобы найти бангалорское время, вы можете сделать так:
>>> # Преобразуем во время по Бангалору >>> bang_d = loc_d.astimezone(timezone('Asia/Kolkata')) >>> print(bang_d) 2012-12-21 21:00:00+05:30 >>>
Если вы собираетесь выполнять арифметические операции над локализованными датами, вам нужно знать о переводах времени с летнего на зимнее и прочих подобных деталях. Например, в 2013 году стандартное летнее время США началось 13 марта в 2:00 ночи по местному времени городов (время было переведено на час вперед). Если бы провели стандартную арифметическую операцию над датами, то получили бы неверный результат. Например:
>>> d = datetime(2013, 3, 10, 1, 45) >>> loc_d = central.localize(d) >>> print(loc_d) 2013-03-10 01:45:00-06:00 >>> later = loc_d + timedelta(minutes=30) >>> print(later) # НЕВЕРНО! НЕВЕРНО! 2013-03-10 02:15:00-06:00 >>>
Ответ получается неверным, поскольку он не учитывает перевод местного времени на один час. Чтобы исправить это, используйте метод временных зон normalize(). Например:
>>> from datetime import timedelta >>> later = central.normalize(loc_d + timedelta(minutes=30)) >>> print(later) 2013-03-10 03:15:00-05:00 >>>
Чтобы предотвратить взрыв головы, используйте обычную стратегию работы с локальным временем: преобразование всех дат в UTC и использование уже их для хранения и обработки. Например:
>>> print(loc_d) 2013-03-10 01:45:00-06:00 >>> utc_d = loc_d.astimezone(pytz.utc) >>> print(utc_d) 2013-03-10 07:45:00+00:00 >>>
Если время уже в UTC, вы можете не волноваться по поводу проблем, связанных с переходом на летнее время, а также прочих подобных вещах. Вы свободно можете выполнять арифметические операции с датами. Если же вы хотите вывести дату в локальном времени, просто сконвертируйте в нужную временную зону. Например:
>>> later_utc = utc_d + timedelta(minutes=30) >>> print(later_utc.astimezone(central)) 2013-03-10 03:15:00-05:00 >>>
С использованием временных зон есть одна проблема: какие имена временных зон использовать? Например, в этом рецепте мы как-то узнали, что "Asia/ Kolkata" - это правильное название временной зоны для Индии. Чтобы узнать название нужной зоны, поищите в словаре pytz.country_timezones, указывая в качестве ключа код страны по ISO 3166. Например:
>>> print(pytz.country_timezones['IN']) ['Asia/Kolkata'] >>>
Со следующего шага мы начнем рассматривать итераторы и генераторы.