3 Построение даты / времени с учетом часового пояса

По умолчанию все datetime объекты наивны. Для того, чтобы сделать их часовой пояс, знаете, вы должны приложить tzinfo объект, который обеспечивает смещение UTC и часовой пояс аббревиатуры в зависимости от даты и времени.

Фиксированное смещение часовых поясов

Для часовых поясов, которые фиксированное смещение от UTC, в Python 3.2+, то datetime модуль обеспечивает timezone класс, конкретную реализацию tzinfo , который принимает timedelta и (опционально) параметр имени:

из datetime импорт datetime, timedelta, timezone JST = часовой пояс (timedelta (часы = + 9)) dt = datetime (2015, 1, 1, 12, 0, 0, tzinfo = JST) print (dt) # 2015-01-01 12: 00: 00 + 09: 00 print (dt.tzname ()) # UTC + 09: 00 dt = datetime (2015, 1, 1, 12, 0, 0, tzinfo = timezone (timedelta (hours = 9), 'JST')) print (dt.tzname) # 'JST'

Для версий Python до 3.2, необходимо использовать библиотеку третьей стороны, например, dateutil . dateutil обеспечивает эквивалентный класс, tzoffset , который (в версии 2.5.3) принимает аргументы вида dateutil.tz.tzoffset(tzname, offset) , где offset задается в секундах:

из datetime импорт datetime, timedelta из dateutil import tz JST = tz.tzoffset ('JST', 9 * 3600) # 3600 секунд в час dt = datetime (2015, 1, 1, 12, 0, tzinfo = JST) печать (dt ) # 2015-01-01 12: 00: 00 + 09: 00 print (dt.tzname) # 'JST'

Зоны с летним временем

Для зон с переходом на летнее время стандартные библиотеки python не предоставляют стандартный класс, поэтому необходимо использовать стороннюю библиотеку. pytz и dateutil популярные библиотеки , обеспечивающие классы часовых поясов.

В дополнении к статическим часовым поясам, dateutil обеспечивает классы часовых поясов , которые используют летнее время (см документации для tz модуля ). Вы можете использовать tz.gettz() метод , чтобы получить объект часового пояса, который затем может быть передан непосредственно к datetime и datetime конструктора:

 from datetime import datetime
from dateutil import tz
local = tz.gettz() # Local time
PT = tz.gettz('US/Pacific') # Pacific time

dt_l = datetime(2015, 1, 1, 12, tzinfo=local) # I am in EST
dt_pst = datetime(2015, 1, 1, 12, tzinfo=PT)
dt_pdt = datetime(2015, 7, 1, 12, tzinfo=PT) # DST is handled automatically
print(dt_l)
# 2015-01-01 12:00:00-05:00
print(dt_pst)
# 2015-01-01 12:00:00-08:00
print(dt_pdt)
# 2015-07-01 12:00:00-07:00

 

ВНИМАНИЕ: В версии 2.5.3, dateutil не обрабатывает неоднозначные DateTimes правильно, и всегда будет по умолчанию на более поздний срок. Там нет никакого способа построить объект с dateutil временной зоны , представляющей, например 2015-11-01 1:30 EDT-4 , так как это в течение времени перехода летнее.

Все случаи краев обрабатываются должным образом при использовании pytz , но pytz временных зоны не должны быть непосредственно присоединены к часовым поясам через конструктор. Вместо этого, pytz временная зона должна быть прикреплена с помощью часового пояса localize метод:

 from datetime import datetime, timedelta
import pytz

PT = pytz.timezone('US/Pacific')
dt_pst = PT.localize(datetime(2015, 1, 1, 12))
dt_pdt = PT.localize(datetime(2015, 11, 1, 0, 30))
print(dt_pst)
# 2015-01-01 12:00:00-08:00
print(dt_pdt)
# 2015-11-01 00:30:00-07:00

 

Имейте в виду , что если вы выполняете DATETIME арифметику на pytz -aware часового пояса, вы должны либо выполнить расчеты в формате UTC (если вы хотите , абсолютное время , прошедшее), или вы должны вызвать normalize() на результат:

 dt_new = dt_pdt + timedelta(hours=3) # This should be 2:30 AM PST
print(dt_new)
# 2015-11-01 03:30:00-07:00
dt_corrected = PT.normalize(dt_new)
print(dt_corrected)
# 2015-11-01 02:30:00-08:00