Как я могу использовать dateutil.tz.tz.tzoffset, чтобы локализовать наивное время в часовом поясе, созданное с использованием strptime? - PullRequest
0 голосов
/ 16 мая 2019

Как я могу использовать объект, имеющий тип dateutil.tz.tz.tzoffset, для локализации наивного объекта datetime с часовым поясом с правильной информацией о часовом поясе и летнем времени, чтобы его можно было правильно преобразовать в UTC? В качестве альтернативы, как я могу преобразовать dateutil.tz.tz.tzoffset в pytz.timezone?

Мне не удалось найти хорошую информацию о локализации объекта datetime с использованием объекта dateutil.tz.tz.tzoffset. Ниже приведены несколько лучших статей, которые я просмотрел.

Справочная информация:

Я имею дело с многочисленными строками дат, большинство из которых не имеют информации о часовом поясе. В некоторых случаях время в GMT, в других - местное. Сначала я должен определить часовой пояс устройства, создающего эти различные журналы, затем проанализировать различные строки даты, добавить часовой пояс добавления, если это местное время, и, наконец, преобразовать его в UTC.

У меня почти все это работает, за исключением единственного надежного способа определения TimeZone - из текстового файла с датой в формате EDT, IST и т. Д., Поэтому я использовал пост с верхним голосованием ниже ссылку, чтобы выполнить это, используя функцию paruser.parse () из dateutil и отправив ей слово для аргумента tzinfos. ( Анализ строки даты / времени с сокращенным именем часового пояса в Python? )

Однако это оставляет меня с DateTime, который имеет тип tzinfo = dateutil.tz.tz.tzoffset. Это нормально для меня, за исключением того, что мне нужно использовать эту tzinfo для локализации строк, которые не содержат информацию о часовом поясе, а тип dateutil.tz.tz.tzoffset не имеет опции локализации, как это делает pytz.timezone, что является ключевым моментом. моей проблемы.

Я делаю это слишком сложно? Должен ли я просто заменить tzinfo в наивном datetime часового пояса на объект dateutil.tz.tz.tzoffset, который я сохранил?

Код:

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

from dateutil.parser import parse as parsedate
import pytz
from pytz import timezone
from datetime import datetime

timestr = 'Sat, 5/01/2019 8:00PM EDT' #only reliable source of timezone info
dtfromstrEDT = parsedate(timestr, tzinfos=tzd) #tzd is created from the above link
mytimeZone = dtfromstrEDT.tzinfo  # save local timezone
dtUTC = dtfromstrEDT.astimezone(pytz.timezone('UTC'))  # convert to utc

Теперь вот новая строка даты наивного часового пояса. Он был записан по местному времени, как указано выше (EDT), и поэтому я хочу использовать сохраненную переменную mytimeZone, чтобы локализовать ее и преобразовать в UTC. Я использую стандартное время strptime, чтобы прочитать его как наивное время. Тем не менее, при использовании mytimeZone для локализации даты и времени Naive происходит сбой. Ошибка ниже. Я понимаю ошибку; но я не знаю, как сделать то, что мне нужно:

timestrnaive = 'Mar 15 12:09:20 2019' #in EDT time, same as above string but without any timezone info
dtfromstrNaive = datetime.strptime(timestrnaive, "%b %d %H:%M:%S %Y")
dtlocalized = mytimeZone.localize(dtfromstrNaive, is_dst=True)  
# the above is where it fails with provided error below
# however I can do this instead if I had a pytz.timezone object:
loc_tz = pytz.timezone('America/New_York')
dtlocalized = loc_tz.localize(dtfromstrNaive, is_dst=True) 
dtUTC2 = dtlocalized.astimezone(pytz.timezone('UTC'))  # convert to utc

Ошибка:

Traceback (most recent call last):
  File "C:\Examples\timezones.py", line 221, in <module>
    dtlocalized = mytimeZone.localize(dtfromstrNaive, is_dst=True)  # convert to whatever tz is stored in self.timeZone
AttributeError: 'tzoffset' object has no attribute 'localize'

Рассмотрено следующее:

Локализация datetime (с учетом часового пояса) из смещения часового пояса - Я не уверен, как применить это к этой проблеме, так как у меня есть объект dateutil.tz.tz.tzoffset, а не необработанное время utc.

Анализ строки даты / времени с сокращенным названием часового пояса в Python? - Это дало мне возможность прочитать данные часового пояса, такие как EDT и PDT.

Как сделать незнакомый часовой пояс даты и времени осведомленным в python - Это не помогает, потому что не решает проблему dateutil.tz.tz.tzoffset, о которой я упоминал.

Ответы [ 2 ]

1 голос
/ 17 мая 2019

Основное заблуждение, которое вы здесь скрываете, заключается в том, что вам нужен метод localize, который является историческим артефактом в pytz, возникшем в эпоху до того, как PEP 495 добавил атрибут «сгиб».Подробнее о причине отклонения pytz от интерфейса стандартной библиотеки вы можете прочитать в этой статье .

. Как вы отметили в своем ответе, за все, что отличается от pytz зон, вы можете просто использовать .replace для создания нового времени и даты с соответствующим часовым поясом.Существует также вспомогательная функция dateutil.utils.default_tzinfo, которая автоматически определяет, является ли дата-время наивным или нет, и присоединяет значение по умолчанию к tzinfo, если это так.

Еще одна вещь, на которую следует обратить вниманиев том, что использование pytz здесь не является необходимым, поскольку dateutil также предоставляет объект UTC, поэтому вы можете сделать что-то вроде этого:

from dateutil import tz
timestrnaive = 'Mar 15 12:09:20 2019'
dtfromstrNaive = datetime.strptime(timestrnaive, "%b %d %H:%M:%S %Y") 
dtlocalized = dtfromstrNaive.replace(tzinfo=mytimeZone)
dtUTC2 = dtlocalized.astimezone(tz.UTC) # Convert to UTC

Таким образом, вам не нужно сохранять какую-либо зависимостьна pytz.

Если вы хотите узнать больше об использовании часовых поясов в Python, я также недавно выступил с докладом об этом на PyCon .

0 голосов
/ 16 мая 2019

После еще нескольких испытаний я понял, что делаю это слишком сложно.Решение было простым:

timestrnaive = 'Mar 15 12:09:20 2019'
dtfromstrNaive = datetime.strptime(timestrnaive, "%b %d %H:%M:%S %Y") 
dtlocalized = dtfromstrNaive.replace(tzinfo=mytimeZone)
dtUTC2 = dtlocalized.astimezone(pytz.timezone('UTC'))  # convert to utc

...