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

10 minutos de lectura

avatar de usuario
bebé vitaly

datetime.datetime.utcnow()

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

Esperaría que esto contuviera tzinfo.

  • ¿Cómo convertir un campo de fecha de formato iso normal que es de tipo cadena a formato utc?

    – Navi

    28 mayo 2020 a las 10:40

avatar de usuario
craig mcqueen

Tenga en cuenta que para Python 3.2 en adelante, el datetime el módulo contiene datetime.timezone. la documentación para datetime.utcnow() dice:

Se puede obtener una fecha y hora UTC actual al llamar datetime.now(timezone.utc).

Asi que, datetime.utcnow() no se pone tzinfo para indicar que es UTC, pero datetime.now(datetime.timezone.utc) devuelve la hora UTC con tzinfo establecer.

Entonces puedes hacer:

>>> import datetime
>>> datetime.datetime.now(datetime.timezone.utc)
datetime.datetime(2014, 7, 10, 2, 43, 55, 230107, tzinfo=datetime.timezone.utc)

  • ¿Cuál se prefiere? datetime.now(timezone.utc) o datetime.utcnow(timezone.utc)?

    –Jesse Webb

    10 de noviembre de 2014 a las 20:18

  • datetime.utcnow() no acepta argumentos. Entonces tendría que ser datetime.now(timezone.utc).

    –Craig McQueen

    10 de noviembre de 2014 a las 22:37

  • datetime.now() devolverá la hora de la máquina pero datetime.utcnow() devolverá la hora UTC real.

    – Babú

    13 de junio de 2016 a las 8:08

  • @Babu: datetime.utcnow() no se pone tzinfo para indicar que es UTC. Pero datetime.now(datetime.timezone.utc) devuelve la hora UTC con tzinfo establecer.

    –Craig McQueen

    13 de junio de 2016 a las 23:25

  • Creo que esta es la solución adecuada ahora, no debería ser necesario agregar una dependencia externa para especificar los metadatos de la zona horaria cuando ya es explícitamente UTC

    – Jacopofar

    13 de junio de 2019 a las 12:57

avatar de usuario
Juan La Rooy

Eso significa que es ingenuo de zona horaria, por lo que no puede usarlo con datetime.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 a datetime.now() directamente:

#!/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 usar tz.localize(datetime.now()) — puede fallar durante la transición del final del horario de verano cuando la hora local es ambigua.

  • Pero no hay una buena razón para que sea ingenuo de la zona horaria: se especifica que es UTC. ¿Por qué necesita buscar una biblioteca de terceros para que funcione correctamente?

    – Mark Ransom

    25 de febrero de 2010 a las 4:51

  • Estoy de acuerdo; para mí los tiempos ‘ingenuos’ son completamente inútiles. Hay una discusión en la lista de python en este momento sobre agregar pytz a stdlib; el problema no es la licencia, sino el hecho de que los datos de la zona horaria se actualizan con tanta frecuencia (que Python en sí mismo 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 en 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

    25 de febrero de 2010 a las 16:41

  • @bobince ¿Por qué pytz y las bibliotecas de fecha y hora estándar no funcionan para usted? El núcleo de Python y pytz que evolucionan como proyectos independientes reducen 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 las 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 de tzinfo…” es genial porque es simple, ¿por qué hacer una excepción aquí?

    – Derek Litz

    5 de abril de 2013 a las 17:23


  • ¿Qué tal si solo u=datetime.now(pytz.utc)

    –Craig McQueen

    10 de julio de 2014 a las 1:41

  • @bain: no usar tz.localize(datetime.now()); usar datetime.now(tz) en cambio.

    – jfs

    15 de junio de 2015 a las 7:09

avatar de usuario
marca rescate

Las bibliotecas estándar de Python no incluían ninguna clase de 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 es lo suficientemente incontrovertible como para tener una implementación estándar. Aunque no hubo implementación en la biblioteca, hay una que se da como ejemplo en el 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 UTC tzinfo objeto, todavía no puedes 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 un UTC tzinfo clase 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. Ver PEP 615 — Compatibilidad con la base de datos de zonas horarias de la IANA en la biblioteca estándar para todos los detalles.

  • Imagínese por qué esta clase no se proporcionó en primer lugar (y, lo que es más importante, se usó para datetime objetos creados por utcnow())…

    – André Carón

    6 de febrero de 2013 a las 21:46

  • @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 struct El módulo haría conversiones automáticas de Unicode a cadena de bytes, y la decisión final fue romper la compatibilidad con versiones anteriores de Python 3 para evitar una mala decisión.

    – Mark Ransom

    24 de junio de 2013 a las 19:26

  • Estoy estupefacto de que Python tzinfo la documentación incluye ejemplos de código para implementarlo, ¡pero no incluyen esa funcionalidad en datetime en sí! docs.python.org/2/library/datetime.html#datetime.tzinfo.fromutc

    – Sr. Lance E Sloan

    1 de septiembre de 2016 a las 22:18


  • Además, la clase UTC de ejemplo que se muestra aquí es casi exactamente lo que pytz la implementación del módulo contiene. Agrega algunos métodos útiles.

    – Sr. Lance E Sloan

    1 sep 2016 a las 22:33

  • @LS sí, pytz es un gran recurso. Cuando edité mi respuesta para incluir el código de ejemplo, alguien más ya lo había sugerido y no quería robarles el protagonismo.

    – Mark Ransom

    1 sep 2016 a las 22:51

avatar de usuario
bbengfort

los pytz módulo es una opción, y hay otra python-dateutilque aunque también es un paquete de terceros, es posible que ya esté disponible según sus otras dependencias y sistema operativo.

Solo quería incluir esta metodología como referencia, si ya instaló python-dateutil para otros fines, puede utilizar su tzinfo en lugar de duplicar con pytz

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 estar de acuerdo en que las llamadas a utcnow debe incluir la información de la zona horaria UTC. Sospecho que esto no está incluido porque la biblioteca de fecha y hora nativa tiene por defecto las fechas y horas ingenuas para la compatibilidad cruzada.

avatar de usuario
nacido en el norte

Para agregar timezone información en Python 3.2+

import datetime

>>> d = datetime.datetime.now(tz=datetime.timezone.utc)
>>> print(d.tzinfo)
'UTC+00:00'

  • AttributeError: 'module' object has no attribute 'timezone' Python 2.7.13 (predeterminado, 19 de enero de 2017, 14:48:08)

    –Marcin Owsiany

    28 de noviembre de 2017 a las 11:44


  • @MarcinOwsiany prueba: from datetime import datetime, timezone luego invocar con datetime.now(tz=timezone.utc)

    – s2t2

    15 de agosto de 2020 a las 18:44


  • Esta es la mejor manera de obtener un objeto de fecha y hora consciente de la zona horaria UTC sin usar ningún módulo de Python de terceros como pytz. | Sólo para añadir una cosa más. Si desea obtener un objeto de fecha y hora LOCAL consciente de la zona horaria sin usar ningún módulo adicional, simplemente agregue astimezone (): d.astimezone()

    –Saurav Kumar

    18 de septiembre de 2020 a las 14:05

Julien Danjou escribió un buen artículo explicando por qué nunca deberías lidiar con las zonas horarias. Un experto:

De hecho, la API de fecha y hora de Python siempre devuelve objetos de fecha y hora inconscientes, lo cual es muy desafortunado. De hecho, tan pronto como obtenga uno de estos objetos, no hay forma de saber cuál es la zona horaria, por lo tanto, estos objetos son bastante “inútiles” por sí solos.

Por desgracia, a pesar de que puede utilizar utcnow()aún no verá la información de la zona horaria, como descubrió.

Recomendaciones:

  • Utilice siempre consciente datetime objetos, es decir, con información de la zona horaria. Eso asegura que pueda compararlos directamente (consciente y no consciente) datetime
    los objetos no son comparables) y los devolverá correctamente a los usuarios. Aprovechar pytz tener objetos de zona horaria.

  • Usar ISO 8601 como el formato de cadena de entrada y salida. Usar datetime.datetime.isoformat() para devolver las marcas de tiempo como una cadena formateada 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 en iso8601, que devuelve marcas de tiempo con información de zona horaria correcta. Esto hace que las marcas de tiempo sean directamente comparables.

  • AttributeError: 'module' object has no attribute 'timezone' Python 2.7.13 (predeterminado, 19 de enero de 2017, 14:48:08)

    –Marcin Owsiany

    28 de noviembre de 2017 a las 11:44


  • @MarcinOwsiany prueba: from datetime import datetime, timezone luego invocar con datetime.now(tz=timezone.utc)

    – s2t2

    15 de agosto de 2020 a las 18:44


  • Esta es la mejor manera de obtener un objeto de fecha y hora consciente de la zona horaria UTC sin usar ningún módulo de Python de terceros como pytz. | Sólo para añadir una cosa más. Si desea obtener un objeto de fecha y hora LOCAL consciente de la zona horaria sin usar ningún módulo adicional, simplemente agregue astimezone (): d.astimezone()

    –Saurav Kumar

    18 de septiembre de 2020 a las 14:05

el comportamiento de datetime.datetime.utcnow() devolver la hora UTC como un objeto ingenuo de fecha y hora es obviamente problemático y debe solucionarse. Puede dar lugar a resultados inesperados si la zona horaria local de su sistema no es UTC, ya que la biblioteca de fecha y hora supone que el objeto ingenuo de fecha y hora representa la hora local del sistema. Por ejemplo, datetime.datetime.utcnow().timestaamp() da una marca de tiempo de 4 horas antes del valor correcto en mi computadora. Además, a partir de Python 3.6, datetime.astimezone() se puede llamar en instancias de fecha y hora ingenuas, pero datetime.datetime.utcnow().astimezone(any_timezone) da un resultado incorrecto a menos que la zona horaria local de su sistema sea UTC.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad