¿Por qué datetime.datetime.utcnow() no contiene información de zona horaria?

Resuelto Vitaly Babiy asked hace 14 años • 10 respuestas
datetime.datetime.utcnow()

¿Por qué esto datetimeno tiene ninguna información de zona horaria dado que es explícitamente UTC datetime?

Esperaría que esto contuviera tzinfo.

Vitaly Babiy avatar Feb 25 '10 11:02 Vitaly Babiy
Aceptado

Tenga en cuenta que para Python 3.2 en adelante, el datetimemó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 tzinfopara 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.UTCun equivalente a datetime.timezone.utc. Así que tú también puedes hacerlo datetime.datetime.now(datetime.UTC).

Craig McQueen avatar Jul 10 '2014 02:07 Craig McQueen

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.

John La Rooy avatar Feb 25 '2010 04:02 John La Rooy

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 tzinfodocumentació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 tzinfoobjeto 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 tzinfoclase UTC en la biblioteca:

from datetime import datetime, timezone 

now = datetime.now(timezone.utc)

En Python 3.9 crearon tzinfoclases 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.

Mark Ransom avatar Feb 25 '2010 04:02 Mark Ransom