Funciona para cualquier zona horaria, incluidas las que observan el horario de verano (DST), es decir, funciona para zonas horarias que pueden tener diferentes compensaciones de utc en diferentes momentos (compensación de utc no fija). No lo use tz.localize(datetime.now()): puede fallar durante la transición de finalización del horario de verano cuando la hora local es ambigua.
Pero no hay una buena razón para que sea ingenua en la zona horaria: se especifica que es UTC. ¿Por qué necesita buscar una biblioteca de terceros para que funcione correctamente?
Mark Ransom
44
Estoy de acuerdo; para mí los tiempos "ingenuos" son completamente inútiles. Hay una discusión en la lista de python en este momento acerca de agregar pytz a stdlib; El problema no es la concesión de licencias, sino el hecho de que los datos de la zona horaria se actualizan con tanta frecuencia (que Python no puede ser) Además, pytz no implementa la interfaz tzinfo de la manera esperada, por lo que puede obtener errores si intenta usar algunas de las zonas horarias de la ciudad astimezone. Por lo tanto, datetime no solo no tiene zonas horarias nativas, sino que la única implementación ampliamente disponible de tzinfo no cumple con el supuesto estándar.
bobince
55
@bobince ¿Por qué Pytz y las bibliotecas de fecha y hora estándar no funcionan para usted? El núcleo de Python y Pytz evolucionando como proyectos independientes reduce la complejidad logística para el equipo central. Sí, reducir la complejidad para el equipo central de Python aumenta la complejidad para todos los usuarios de Python que necesitan lidiar con zonas horarias, pero confío en que tomaron esta decisión por una buena razón. La regla "La biblioteca estándar no tiene instancias tzinfo ..." es genial porque es simple, ¿por qué hacer una excepción aquí?
Derek Litz
15
¿Qué tal solou=datetime.now(pytz.utc)
Craig McQueen
44
@bain: no usar tz.localize(datetime.now()); utilizar datetime.now(tz)en su lugar.
¿Cuál es el preferido? datetime.now(timezone.utc)o datetime.utcnow(timezone.utc)?
Jesse Webb
8
datetime.utcnow()No toma argumentos. Entonces tendría que ser así datetime.now(timezone.utc).
Craig McQueen
1
datetime.now()devolverá la hora de la máquina pero datetime.utcnow()devolverá la hora UTC real.
Babu
13
@Babu: datetime.utcnow()no está configurado tzinfopara indicar que es UTC. Pero datetime.now(datetime.timezone.utc)devuelve la hora UTC contzinfo set.
Craig McQueen
@CraigMcQueen Entonces, si pasamos un tzobjeto en el constructor ahora, ¿devolverá la hora de esa zona horaria? ¡Okay! Gracias por señalarlo.
Babu
71
Las bibliotecas estándar de Python no incluyen ninguna clase de tzinfo (pero vea pep 431 ). Solo 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.
Editar: aunque no hay implementación en la biblioteca, hay una dada 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()
Para usarlo, para obtener la hora actual como un objeto de fecha y hora consciente:
from datetime import datetime
now = datetime.now(utc)
Hay datetime.timezone.utcen Python 3.2+:
from datetime import datetime, timezone
now = datetime.now(timezone.utc)
Averigüe por qué esta clase no se proporcionó en primer lugar (y, lo que es más importante, se usó para datetimeobjetos creados por utcnow()) ...
André Caron
17
El objeto de zona horaria timezone.utcfinalmente se ha agregado a Python 3.2. Para la compatibilidad con versiones anteriores, utcnow()aún devuelve un objeto de tiempo sin zona horaria, pero puede obtener lo que desea llamando now(timezone.utc).
mhsmith
44
@rgove, ese es el tipo de corrección de errores que se suponía que era un juego justo para Python 3. No deberían haberse preocupado por la compatibilidad con versiones anteriores. Hay otro ejemplo que leí en los últimos días: el structmódulo haría conversiones automáticas de Unicode a bytestring, y la decisión final fue romper la compatibilidad con versiones anteriores de Python 3 para evitar que una mala decisión avance.
@LS sí, pytzes un gran recurso. Cuando edité mi respuesta para poner el código de ejemplo, otra persona ya lo había sugerido y no quería robarles el trueno.
Mark Ransom
20
El pytzmódulo es una opción, y hay otra.python-dateutil , que aunque también es un paquete de terceros, ya puede estar disponible dependiendo de sus otras dependencias y sistema operativo.
Solo quería incluir esta metodología como referencia; si ya la instaló python-dateutilpara otros fines, puede usarla en tzinfolugar de duplicarla conpytz
import datetime
import dateutil.tz
# Get the UTC time with datetime.now:
utcdt = datetime.datetime.now(dateutil.tz.tzutc())# Get the UTC time with datetime.utcnow:
utcdt = datetime.datetime.utcnow()
utcdt = utcdt.replace(tzinfo=dateutil.tz.tzutc())# For fun- get the local time
localdt = datetime.datetime.now(dateutil.tz.tzlocal())
Tiendo a aceptar que las llamadas a utcnowdeben incluir la información de la zona horaria UTC. Sospecho que esto no está incluido porque la biblioteca nativa de fecha y hora por defecto es fecha y hora ingenua para compatibilidad cruzada.
Estaba usando la llamada datetime.datetime.utcfromtimestamp (), y necesitaba agregar tzinfo, la segunda solución funcionó para mí: utcdt = datetime.datetime.utcfromtimestamp(1234567890).replace(dateutil.tz.tzutc())
Desde mi programa ya estaba importando dateutilpara dateutil.parser, me ha gustado esta solución mejor. Era tan simple como: utcCurrentTime = datetime.datetime.now(tz=dateutil.tz.tzutc()). ¡¡Viola!!
De hecho, Python datetime API siempre devuelve objetos datetime inconscientes, lo cual es muy desafortunado. De hecho, tan pronto como obtienes uno de este objeto, no hay forma de saber cuál es la zona horaria, por lo tanto, estos objetos son bastante "inútiles" por sí mismos.
Por desgracia, aunque pueda usarlo utcnow(), no verá la información de la zona horaria, como descubrió.
Recomendaciones:
Utilice siempre datetimeobjetos conscientes , es decir, con información de zona horaria. Eso asegura que pueda compararlos directamente (los datetime
objetos conscientes e inconscientes no son comparables) y los devolverá correctamente a los usuarios. Aproveche pytz para tener objetos de zona horaria.
Utilice ISO 8601 como formato de cadena de entrada y salida. Se usa datetime.datetime.isoformat()para devolver marcas de tiempo como cadenas formateadas con ese formato, que incluye la información de la zona horaria.
Si necesita analizar cadenas que contienen marcas de tiempo con formato ISO 8601, puede confiar iso8601, lo que devuelve marcas de tiempo con la información de zona horaria correcta. Esto hace que las marcas de tiempo sean directamente comparables.
Esta es una recomendación ligeramente engañosa. La regla general es, nunca trate con zonas horarias. Siempre almacene y transmita tz objetos utc no conocidos (objetos de época). La zona horaria solo debe calcularse en el momento de la representación en la interfaz de usuario
nehem
1
Parece que ya coincide con los pensamientos de Julien bastante bien. ¿Cuáles de sus recomendaciones específicas (como se mencionó anteriormente) son engañosas?
Joe D'Andrea
10
Para agregar timezoneinformación en Python 3.2+
import datetime
>>> d = datetime.datetime.now(tz=datetime.timezone.utc)>>>print(d.tzinfo)'UTC+00:00'
Por lo que puedo decir de docs.python.org/library/datetime.html , una fecha y hora sin tzinfo es aquella en la que la zona horaria no está especificada. Aquí se ha especificado la zona horaria , por lo que lógicamente debería estar presente. Hay una gran diferencia entre una fecha / hora sin una zona horaria asociada y una que definitivamente está en UTC. (Idealmente, deberían ser diferentes tipos de IMO, pero ese es otro asunto ...)
Jon Skeet
@ JonSkeet Creo que te estás perdiendo el punto de Ignacio de que UTC no es una zona horaria. Increíble que esta respuesta tiene -9 puntuación mientras escribo esto ...
CS
3
@CS: Bueno, Ignacio nunca dijo que ... y aunque estrictamente hablando, UTC no es una zona horaria, generalmente se trata como una para hacer la vida considerablemente más simple (incluso en Python, por ejemplo, con pytz.utc). Tenga en cuenta que hay una gran diferencia entre un valor cuyo desplazamiento de UTC es desconocido y uno donde se sabe que es 0. Esto último es lo que utcnow()debería devolver, IMO. Eso encajaría con "Un objeto consciente se utiliza para representar un momento específico en el tiempo que no está abierto a interpretación" según la documentación.
Respuestas:
Eso significa que es una zona horaria ingenua, por lo que no puede usarla con
datetime.astimezone
puedes darle una zona horaria como esta
ahora puedes cambiar las zonas horarias
Para obtener la hora actual en una zona horaria determinada, puede pasar tzinfo
datetime.now()
directamente a:Funciona para cualquier zona horaria, incluidas las que observan el horario de verano (DST), es decir, funciona para zonas horarias que pueden tener diferentes compensaciones de utc en diferentes momentos (compensación de utc no fija). No lo use
tz.localize(datetime.now())
: puede fallar durante la transición de finalización del horario de verano cuando la hora local es ambigua.fuente
astimezone
. Por lo tanto, datetime no solo no tiene zonas horarias nativas, sino que la única implementación ampliamente disponible de tzinfo no cumple con el supuesto estándar.u=datetime.now(pytz.utc)
tz.localize(datetime.now())
; utilizardatetime.now(tz)
en su lugar.Tenga en cuenta que para Python 3.2 en adelante, el
datetime
módulo contienedatetime.timezone
. La documentación paradatetime.utcnow()
dice:Entonces puedes hacer:
fuente
datetime.now(timezone.utc)
odatetime.utcnow(timezone.utc)
?datetime.utcnow()
No toma argumentos. Entonces tendría que ser asídatetime.now(timezone.utc)
.datetime.now()
devolverá la hora de la máquina perodatetime.utcnow()
devolverá la hora UTC real.datetime.utcnow()
no está configuradotzinfo
para indicar que es UTC. Perodatetime.now(datetime.timezone.utc)
devuelve la hora UTC contzinfo
set.tz
objeto en el constructor ahora, ¿devolverá la hora de esa zona horaria? ¡Okay! Gracias por señalarlo.Las bibliotecas estándar de Python no incluyen ninguna clase de tzinfo (pero vea pep 431 ). Solo 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.
Editar: aunque no hay implementación en la biblioteca, hay una dada como ejemplo en la
tzinfo
documentación .Para usarlo, para obtener la hora actual como un objeto de fecha y hora consciente:
Hay
datetime.timezone.utc
en Python 3.2+:fuente
datetime
objetos creados porutcnow()
) ...timezone.utc
finalmente se ha agregado a Python 3.2. Para la compatibilidad con versiones anteriores,utcnow()
aún devuelve un objeto de tiempo sin zona horaria, pero puede obtener lo que desea llamandonow(timezone.utc)
.struct
módulo haría conversiones automáticas de Unicode a bytestring, y la decisión final fue romper la compatibilidad con versiones anteriores de Python 3 para evitar que una mala decisión avance.tzinfo
documentación de Python incluya ejemplos de código para implementarlo, ¡pero no incluyen esa funcionalidad en fecha y hora! docs.python.org/2/library/datetime.html#datetime.tzinfo.fromutcpytz
es un gran recurso. Cuando edité mi respuesta para poner el código de ejemplo, otra persona ya lo había sugerido y no quería robarles el trueno.El
pytz
módulo es una opción, y hay otra.python-dateutil
, que aunque también es un paquete de terceros, ya puede estar disponible dependiendo de sus otras dependencias y sistema operativo.Solo quería incluir esta metodología como referencia; si ya la instaló
python-dateutil
para otros fines, puede usarla entzinfo
lugar de duplicarla conpytz
Tiendo a aceptar que las llamadas a
utcnow
deben incluir la información de la zona horaria UTC. Sospecho que esto no está incluido porque la biblioteca nativa de fecha y hora por defecto es fecha y hora ingenua para compatibilidad cruzada.fuente
utcdt = datetime.datetime.utcfromtimestamp(1234567890).replace(dateutil.tz.tzutc())
datetime.now(pytz_tz)
eso siempre funciona;datetime.now(dateutil.tz.tzlocal())
puede fallar durante las transiciones DST . PEP 495 - La desambiguación de la hora local podría mejorar ladateutil
situación en el futuro.utc_dt = datetime.fromtimestamp(1234567890, dateutil.tz.tzutc())
(nota:dateutil
con un desplazamiento utc no fijo (comodateutil.tz.tzlocal()
) puede fallar aquí , use unapytz
solución basada en su lugar ).dateutil
paradateutil.parser
, me ha gustado esta solución mejor. Era tan simple como:utcCurrentTime = datetime.datetime.now(tz=dateutil.tz.tzutc())
. ¡¡Viola!!Julien Danjou escribió un buen artículo explicando por qué nunca debes tratar con zonas horarias . Un experto:
Por desgracia, aunque pueda usarlo
utcnow()
, no verá la información de la zona horaria, como descubrió.Recomendaciones:
fuente
Para agregar
timezone
información en Python 3.2+fuente
AttributeError: 'module' object has no attribute 'timezone'
Python 2.7.13 (predeterminado, 19 de enero de 2017, 14:48:08)fuente
Las fechas UTC no necesitan ninguna información de zona horaria ya que son UTC, lo que por definición significa que no tienen compensación.
fuente
pytz.utc
). Tenga en cuenta que hay una gran diferencia entre un valor cuyo desplazamiento de UTC es desconocido y uno donde se sabe que es 0. Esto último es lo queutcnow()
debería devolver, IMO. Eso encajaría con "Un objeto consciente se utiliza para representar un momento específico en el tiempo que no está abierto a interpretación" según la documentación.