Lo que necesito hacer
Tengo un objeto datetime que no conoce la zona horaria, al que necesito agregar una zona horaria para poder compararlo con otros objetos datetime que reconocen la zona horaria. No quiero convertir toda mi aplicación a la zona horaria sin saberlo para este caso heredado.
Lo que he probado
Primero, para demostrar el 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
Primero, probé 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
>>>
No es terriblemente sorprendente que esto haya fallado, ya que en realidad está tratando de hacer una conversión. Reemplazar parecía una mejor opción (según Python: ¿Cómo obtener un valor de datetime.today () que sea "consciente de la zona horaria"? ):
>>> 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
>>>
Pero como puede ver, reemplazar parece establecer el tzinfo, pero no hace que el objeto sea consciente. Me estoy preparando para volver a tratar la cadena de entrada para tener una zona horaria antes de analizarla (estoy usando dateutil para analizar, si eso importa), pero eso parece increíblemente torpe.
Además, he intentado esto en python 2.6 y python 2.7, con los mismos resultados.
Contexto
Estoy escribiendo un analizador para algunos archivos de datos. Hay un formato antiguo que necesito admitir donde la cadena de fecha no tiene un indicador de zona horaria. Ya arreglé la fuente de datos, pero aún necesito admitir el formato de datos heredado. Una conversión única de los datos heredados no es una opción por varias razones comerciales de BS. Si bien, en general, no me gusta la idea de codificar una zona horaria predeterminada, en este caso parece la mejor opción. Sé con bastante confianza que todos los datos heredados en cuestión están en UTC, por lo que estoy dispuesto a aceptar el riesgo de incumplimiento en ese caso.
import datetime; datetime.datetime.now(datetime.timezone.utc)
tz
para ser más legible:datetime.datetime.now(tz=datetime.timezone.utc)
unaware.replace()
volveríaNone
si estuviera modificando elunaware
objeto en el lugar. El REPL muestra que.replace()
devuelve un nuevodatetime
objeto aquí.