Что я должен сделать
У меня есть объект datetime, не поддерживающий часовой пояс, к которому мне нужно добавить часовой пояс, чтобы иметь возможность сравнивать его с другими объектами datetime с учетом часового пояса. Я не хочу преобразовывать все мое приложение в часовой пояс, не подозревая об этом унаследованном случае.
Что я пробовал
Во-первых, чтобы продемонстрировать проблему:
Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import datetime
>>> import pytz
>>> unaware = datetime.datetime(2011,8,15,8,15,12,0)
>>> unaware
datetime.datetime(2011, 8, 15, 8, 15, 12)
>>> aware = datetime.datetime(2011,8,15,8,15,12,0,pytz.UTC)
>>> aware
datetime.datetime(2011, 8, 15, 8, 15, 12, tzinfo=<UTC>)
>>> aware == unaware
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't compare offset-naive and offset-aware datetimes
Сначала я попробовал astimezone:
>>> unaware.astimezone(pytz.UTC)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: astimezone() cannot be applied to a naive datetime
>>>
Неудивительно, что это не удалось, так как он пытается конвертировать. Заменить казалось лучшим выбором (согласно Python: как получить значение datetime.today (), которое «учитывает часовой пояс»? ):
>>> unaware.replace(tzinfo=pytz.UTC)
datetime.datetime(2011, 8, 15, 8, 15, 12, tzinfo=<UTC>)
>>> unaware == aware
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't compare offset-naive and offset-aware datetimes
>>>
Но, как вы можете видеть, замена, кажется, устанавливает tzinfo, но не делает объект осведомленным. Я собираюсь вернуться к лечению входной строки, чтобы иметь часовой пояс перед его синтаксическим анализом (я использую dateutil для анализа, если это имеет значение), но это кажется невероятно грязным.
Кроме того, я пробовал это и в Python 2.6 и Python 2.7, с одинаковыми результатами.
контекст
Я пишу парсер для некоторых файлов данных. Существует старый формат, который мне нужно поддерживать, когда строка даты не имеет индикатора часового пояса. Я уже исправил источник данных, но мне все еще нужно поддерживать устаревший формат данных. Однократное преобразование устаревших данных не подходит по различным причинам бизнес-BS. Хотя в целом мне не нравится идея жесткого кодирования часового пояса по умолчанию, в этом случае он кажется наилучшим вариантом. Я с достаточной уверенностью знаю, что все унаследованные данные находятся в UTC, поэтому я готов принять на себя риск невыполнения этого требования в этом случае.
import datetime; datetime.datetime.now(datetime.timezone.utc)
tz
аргумент, чтобы быть более читабельным:datetime.datetime.now(tz=datetime.timezone.utc)
unaware.replace()
вернулсяNone
бы, если бы он изменялunaware
объект на месте. REPL показывает, что.replace()
возвращает новыйdatetime
объект здесь.