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

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

4b9b3361

Ответ 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'