¿Por qué datetime.datetime.utcnow() no contiene información de zona horaria?
datetime.datetime.utcnow()
¿Por qué esto datetime
no tiene ninguna información de zona horaria dado que es explícitamente UTC datetime
?
Esperaría que esto contuviera tzinfo
.
Tenga en cuenta que para Python 3.2 en adelante, el datetime
módulo contiene datetime.timezone
. La documentación para datetime.utcnow()
dice:
Se puede obtener una fecha y hora UTC actual llamando al .
datetime.now
(
timezone.utc
)
Por lo tanto, datetime.utcnow()
no se establece tzinfo
para indicar que es UTC, pero datetime.now(datetime.timezone.utc)
devuelve la hora UTC con tzinfo
el conjunto.
Entonces puedes hacer:
>>> import datetime
>>> datetime.datetime.now(datetime.timezone.utc)
datetime.datetime(2014, 7, 10, 2, 43, 55, 230107, tzinfo=datetime.timezone.utc)
Desde Python 3.11, también existe datetime.UTC
un equivalente a datetime.timezone.utc
. Así que tú también puedes hacerlo datetime.datetime.now(datetime.UTC)
.
Eso significa que no utiliza zonas horarias, por lo que no puedes usarlo condatetime.astimezone
puedes darle una zona horaria como esta
import pytz # 3rd party: $ pip install pytz
u = datetime.utcnow()
u = u.replace(tzinfo=pytz.utc) #NOTE: it works only with a fixed utc offset
ahora puedes cambiar las zonas horarias
print(u.astimezone(pytz.timezone("America/New_York")))
Para obtener la hora actual en una zona horaria determinada, puede pasar tzinfo datetime.now()
directamente a:
#!/usr/bin/env python
from datetime import datetime
import pytz # $ pip install pytz
print(datetime.now(pytz.timezone("America/New_York")))
Funciona para cualquier zona horaria, incluidas aquellas que observan el horario de verano (DST), es decir, funciona para zonas horarias que pueden tener diferentes compensaciones utc en diferentes momentos (compensación utc no fija). No lo use tz.localize(datetime.now())
: puede fallar durante la transición de fin de horario de verano cuando la hora local es ambigua.
Las bibliotecas estándar de Python no incluyeron ninguna clase tzinfo hasta Python 3.2. Sólo puedo adivinar las razones. Personalmente, creo que fue un error no incluir una clase tzinfo para UTC, porque esa no es lo suficientemente controvertida como para tener una implementación estándar. Aunque no hubo ninguna implementación en la biblioteca, hay una como ejemplo en la tzinfo
documentación .
from datetime import timedelta, tzinfo
ZERO = timedelta(0)
# A UTC class.
class UTC(tzinfo):
"""UTC"""
def utcoffset(self, dt):
return ZERO
def tzname(self, dt):
return "UTC"
def dst(self, dt):
return ZERO
utc = UTC()
Una vez que tenga un tzinfo
objeto UTC, aún no podrá usarlo con utcnow
. Para obtener la hora actual como un objeto de fecha y hora consciente:
from datetime import datetime
now = datetime.now(utc)
En Python 3.2 finalmente pusieron una tzinfo
clase UTC en la biblioteca:
from datetime import datetime, timezone
now = datetime.now(timezone.utc)
En Python 3.9 crearon tzinfo
clases para todas las demás zonas horarias. Consulte PEP 615: compatibilidad con la base de datos de zonas horarias de la IANA en la biblioteca estándar para obtener todos los detalles.