Що мені потрібно зробити
У мене є невідомий часовий пояс об'єкт дати, до якого мені потрібно додати часовий пояс, щоб мати можливість порівнювати його з іншими об'єктами дат, відомих часовим поясом. Я не хочу перетворювати всю свою програму на часовий пояс, не знаючи для цього одного застарілого випадку.
Що я пробував
По-перше, щоб продемонструвати проблему:
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
По-перше, я спробував астимезон:
>>> 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, з однаковими результатами.
Контекст
Я пишу парсер для деяких файлів даних. Існує старий формат, який мені потрібно підтримувати, коли рядок дати не має індикатора часового поясу. Я вже виправив джерело даних, але мені ще потрібно підтримати застарілий формат даних. Одноразове перетворення застарілих даних не є можливим для різних бізнес-причин. Хоча взагалі мені не подобається ідея жорсткого кодування часового поясу за замовчуванням, в цьому випадку це здається найкращим варіантом. Я знаю з розумною впевненістю, що всі старі дані, що розглядаються, перебувають у UTC, тому я готовий прийняти ризик дефолту до цього в цьому випадку.
import datetime; datetime.datetime.now(datetime.timezone.utc)
tz
аргумент, щоб він був більш зрозумілим:datetime.datetime.now(tz=datetime.timezone.utc)
unaware.replace()
повернеться,None
якби він мінявunaware
об'єкт на місці. REPL показує, що тут.replace()
повертається новийdatetime
об’єкт.