Cosa devo fare
Ho un oggetto datetime ignaro del fuso orario, al quale devo aggiungere un fuso orario per poterlo confrontare con altri oggetti datetime sensibili al fuso orario. Non voglio convertire la mia intera applicazione in fuso orario ignaro di questo caso precedente.
Quello che ho provato
Innanzitutto, per dimostrare il problema:
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
Innanzitutto, ho provato 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
>>>
Non è terribilmente sorprendente che questo sia fallito, dal momento che sta effettivamente cercando di fare una conversione. Sostituire sembrava una scelta migliore (secondo Python: come ottenere un valore di datetime.today () che è "timezone aware"? ):
>>> 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
>>>
Ma come puoi vedere, sostituire sembra impostare tzinfo, ma non rendere consapevole l'oggetto. Mi sto preparando a ricorrere al dottore della stringa di input per avere un fuso orario prima di analizzarlo (sto usando dateutil per l'analisi, se questo è importante), ma sembra incredibilmente kludgy.
Inoltre, ho provato questo in entrambi Python 2.6 e Python 2.7, con gli stessi risultati.
Contesto
Sto scrivendo un parser per alcuni file di dati. C'è un vecchio formato che devo supportare in cui la stringa della data non ha un indicatore del fuso orario. Ho già riparato l'origine dati, ma devo ancora supportare il formato dati legacy. Una conversione una tantum dei dati legacy non è un'opzione per vari motivi di business BS. Mentre in generale, non mi piace l'idea di codificare in modo rigido un fuso orario predefinito, in questo caso sembra l'opzione migliore. So con ragionevole certezza che tutti i dati legacy in questione sono in UTC, quindi sono pronto ad accettare il rischio di inadempienza in questo caso.
import datetime; datetime.datetime.now(datetime.timezone.utc)
tz
arg chiamato per essere più leggibile:datetime.datetime.now(tz=datetime.timezone.utc)
unaware.replace()
ritornerebbeNone
se stesse modificando l'unaware
oggetto sul posto. Il REPL mostra che.replace()
restituiscedatetime
qui un nuovo oggetto.