Python datetime strptime() и strftime(): как сохранить информацию о часовом поясе - программирование
Подтвердить что ты не робот

Python datetime strptime() и strftime(): как сохранить информацию о часовом поясе

Смотрите следующий код:

import datetime
import pytz

fmt = '%Y-%m-%d %H:%M:%S %Z'

d = datetime.datetime.now(pytz.timezone("America/New_York"))
d_string = d.strftime(fmt)
d2 = datetime.datetime.strptime(d_string, fmt)
print d_string 
print d2.strftime(fmt)

вывод

2013-02-07 17:42:31 EST
2013-02-07 17:42:31 

Информация о часовом поясе просто потерялась в переводе.

Если я переключу '% Z' на '% z', я получаю

ValueError: 'z' is a bad directive in format '%Y-%m-%d %H:%M:%S %z'

Я знаю, что могу использовать python-dateutil, но я просто нашел это bizzare, что я не могу достичь этой простой функции в datetime и должен ввести больше зависимости?

4b9b3361

Ответ 1

Часть проблемы здесь состоит в том, что строки, обычно используемые для представления часовых поясов, на самом деле не уникальны. "EST" означает только "America/New_York" для людей в Северной Америке. Это ограничение в API-интерфейсе C, а решение Python - это добавить все функции tz в любую будущую версию в любой момент, если кто-то захочет написать PEP.

Вы можете форматировать и анализировать часовой пояс в качестве смещения, но это теряет информацию о летнем/летнем времени (например, вы не можете отличить "Америку/Феникс" от "America/Los_Angeles" летом). Вы можете отформатировать часовой пояс как аббревиатуру из 3 букв, но вы не сможете ее отменить.

Если вы хотите что-то нечеткое и неоднозначное, но обычно то, что вы хотите, вам нужна сторонняя библиотека, например dateutil.

Если вы хотите что-то действительно недвусмысленное, просто добавьте фактическое имя tz в локальную строку datetime и разделите его на другом конце:

d = datetime.datetime.now(pytz.timezone("America/New_York"))
dtz_string = d.strftime(fmt) + ' ' + "America/New_York"

d_string, tz_string = dtz_string.rsplit(' ', 1)
d2 = datetime.datetime.strptime(d_string, fmt)
tz2 = pytz.timezone(tz_string)

print dtz_string 
print d2.strftime(fmt) + ' ' + tz_string

Или... на полпути между этими двумя, вы уже используете библиотеку pytz, которая может анализировать (в соответствии с некоторыми произвольными, но четко определенными правилами неоднозначности) форматы, такие как "EST". Итак, если вы действительно этого хотите, вы можете оставить %Z на стороне форматирования, затем вытащить его и проанализировать с помощью pytz.timezone(), прежде чем передать остальное на strptime.

Ответ 2

К сожалению, strptime() может обрабатывать только часовой пояс, настроенный вашей ОС, а затем только как временное смещение. Из документа :

Поддержка директивы %Z основана на значениях, содержащихся в tzname, и является ли значение daylight истинным. Из-за этого он зависит от платформы, за исключением признания UTC и GMT, которые всегда известны (и считаются часами без учета летнего времени).

strftime() официально не поддерживает %Z.

Задерживается python-dateutil для поддержки разбора часового пояса, я боюсь.

Ответ 3

Вот мой ответ в Python 2.7

Печать текущего времени с часовым поясом

from datetime import datetime
import tzlocal  # pip install tzlocal

print datetime.now(tzlocal.get_localzone()).strftime("%Y-%m-%d %H:%M:%S %z")

Печать текущего времени с определенным часовым поясом

from datetime import datetime
import pytz # pip install pytz

print datetime.now(pytz.timezone('Asia/Taipei')).strftime("%Y-%m-%d %H:%M:%S %z")

Он напечатает что-то вроде

2017-08-10 20:46:24 +0800