Python: strftime() UTC Offset Не работает как ожидается в Windows
Каждый раз, когда я использую:
time.strftime("%z")
Я получаю:
Eastern Daylight Time
Однако мне хотелось бы, чтобы UTC смещалось в форме + HHMM или -HHMM. Я даже попробовал:
time.strftime("%z")
Что еще дает:
Eastern Daylight Time
Я прочитал несколько других сообщений, связанных с strftime(), и% z всегда, кажется, возвращает смещение UTC в правильном формате + HHMM или -HHMM. Как получить strftime() для вывода в формате + HHMM или -HHMM для python 3.3?
Изменить: я запускаю Windows 7
Ответы
Ответ 1
Для правильного решения см. ответ abarnerts ниже.
Вы можете использовать time.altzone
, который возвращает отрицательное смещение в секундах. Например, Im on CEST на данный момент (UTC + 2), поэтому я получаю следующее:
>>> time.altzone
-7200
И чтобы поместить его в желаемый формат:
>>> '{}{:0>2}{:0>2}'.format('-' if time.altzone > 0 else '+', abs(time.altzone) // 3600, abs(time.altzone // 60) % 60)
'+0200'
Как указано в комментариях, time.altzone
дает смещение, когда DST активен, а time.timezone
делает это, когда DST не активен. Чтобы выяснить, что использовать, вы можете сделать то, что Я. Ф. Себастьян предложил в своем ответе на другой вопрос. Таким образом, вы можете получить правильное смещение следующим образом:
time.altzone if time.daylight and time.localtime().tm_isdst > 0 else time.timezone
Как также предлагает он, вы можете использовать следующее в Python 3, чтобы получить желаемый формат, используя datetime.timezone:
>>> datetime.now(timezone.utc).astimezone().strftime('%z')
'+0200'
Ответ 2
В 2.x, если вы посмотрите на документы для time.strftime
, они даже не упоминают %z
. Это не гарантировалось, что оно существует вообще, а тем более быть последовательным на разных платформах. Фактически, поскольку сноска 1 подразумевает, что она осталась до функции C strftime
. В 3.x, с другой стороны, они упоминают %z
, а сноска, которая объясняет, что она не работает так вы не ожидаете увидеть; что открытая ошибка.
Однако в версии 2.6+ (включая все версии 3.x) datetime.strftime
будет поддерживать %z
как "UTC смещение в форме + HHMM или -HHMM (пустая строка, если объект наивен)." Таким образом, это создает довольно простой способ: используйте datetime
вместо time
. Точно как изменить все зависит от того, что именно вы пытаетесь сделать - используя Python-dateutil tz
, тогда datetime.now(tz.tzlocal()).strftime('%z')
- это способ чтобы получить только локальный часовой пояс, отформатированный как смещение по GMT, но если вы пытаетесь отформатировать полное время, детали будут немного отличаться.
Если вы посмотрите на источник, time.strftime
в основном просто проверяет строку формата для спецификаторов и вызовов, пригодных для платформы нативная функция strftime
, а datetime.strftime
имеет кучу специальной обработки для разных спецификаторов, включая %z
; в частности, он заменит %z
на форматированную версию utcoffset
, прежде чем передавать данные на strftime
. Код изменился несколько раз с 2,7 и даже был радикально реорганизован один раз, но такая же разница в основном существует даже в pre-3.5 туловище.
Ответ 3
Используйте time.timezone
, чтобы получить смещение по времени в секундах.
Отформатируйте его, используя:
("-" if time.timezone > 0 else "+") + time.strftime("%H:%M", time.gmtime(abs(time.timezone)))
чтобы преобразовать его в формат +/- HH: MM.
Кстати, это не ошибка? Согласно strftime
docs.
Также я думал, что этот ответ SO может помочь вам преобразовать из строки смещения зоны в формат HH: MM. Но так как "%z"
работает не так, как ожидалось, я чувствую его спорным.
ПРИМЕЧАНИЕ. time.timezone
невосприимчив к летней экономии.
Ответ 4
Неудивительно, что эта ошибка сохраняется, какова последняя версия Windows, доступная в настоящее время, Win 10 Version 1703 (Creators). Тем не менее, время идет и есть прекрасная библиотека даты и времени, называемая pendulum, которая делает то, о чем спрашивает вопрос. Себастьян Юстас (главный автор продукта?) Показал мне это.
>>> pendulum.now().strftime('%z')
'-0400'
pendulum принимает UTC/GMT, если не указано иное, и сохраняет часовой пояс с объектом даты. Есть много других возможностей, среди которых они:
>>> pendulum.now(tz='Europe/Paris').strftime('%z')
'+0200'
>>> pendulum.create(year=2016, month=11, day=5, hour=16, minute=23, tz='America/Winnipeg').strftime('%z')
'-0500'
>>> pendulum.now(tz='America/Winnipeg').strftime('%z')
'-0500'