yyyy from python datetime timestamp utc

from - python strftime



obtener la marca de tiempo UTC en python con fecha y hora (8)

De hecho, hay un problema con el uso de utcfromtimestamp y la especificación de zonas horarias. Un buen ejemplo / explicación está disponible en la siguiente pregunta:

¿Cómo especificar la zona horaria (UTC) al convertir a tiempo Unix? (Pitón)

¿Hay alguna manera de obtener la marca de tiempo UTC especificando la fecha? Lo que esperaría:

datetime(2008, 1, 1, 0, 0, 0, 0)

debería resultar en

1199145600

Crear un objeto datetime ingenuo significa que no hay información de zona horaria. Si miro la documentación para datetime.utcfromtimestamp, crear una marca de tiempo UTC significa omitir la información de la zona horaria. Así que supongo que crear un objeto naive datetime (como yo lo hice) daría como resultado una marca de tiempo UTC. Sin embargo:

then = datetime(2008, 1, 1, 0, 0, 0, 0) datetime.utcfromtimestamp(float(then.strftime(''%s'')))

resultados en

2007-12-31 23:00:00

¿Todavía hay información de zona horaria oculta en el objeto datetime? ¿Qué estoy haciendo mal?


La manera más simple:

>>> from datetime import datetime >>> dt = datetime(2008, 1, 1, 0, 0, 0, 0) >>> dt.strftime("%s") ''1199163600''

Editar: @ Daniel es correcto, esto lo convertiría en la zona horaria de la máquina. Aquí hay una respuesta revisada:

>>> from datetime import datetime, timezone >>> epoch = datetime(1970, 1, 1, 0, 0, 0, 0, timezone.utc) >>> dt = datetime(2008, 1, 1, 0, 0, 0, 0, timezone.utc) >>> int((dt-epoch).total_seconds()) ''1199145600''

De hecho, ni siquiera es necesario especificar timezone.utc , porque la diferencia de tiempo es la misma siempre que ambas datetime tengan la misma zona horaria (o ninguna zona horaria).

>>> from datetime import datetime >>> epoch = datetime(1970, 1, 1, 0, 0, 0, 0) >>> dt = datetime(2008, 1, 1, 0, 0, 0, 0) >>> int((dt-epoch).total_seconds()) 1199145600


La respuesta aceptada no parece funcionar para mí. Mi solución:

import time utc_0 = int(time.mktime(datetime(1970, 01, 01).timetuple())) def datetime2ts(dt): """Converts a datetime object to UTC timestamp""" return int(time.mktime(dt.utctimetuple())) - utc_0


Otra posibilidad es:

d = datetime.datetime.utcnow() epoch = datetime.datetime(1970,1,1) t = (d - epoch).total_seconds()

Esto funciona ya que tanto "d" como "época" son fechas de programación ingenuas, lo que hace que el operador "-" sea válido y devuelve un intervalo. total_seconds() convierte el intervalo en segundos. Tenga en cuenta que total_seconds() devuelve un flotante, incluso d.microsecond == 0


Si el objeto datetime de entrada está en UTC:

>>> dt = datetime(2008, 1, 1, 0, 0, 0, 0) >>> timestamp = (dt - datetime(1970, 1, 1)).total_seconds() 1199145600.0

Nota: devuelve float, es decir, microsegundos se representan como fracciones de segundo.

Si el objeto de fecha de entrada está en UTC:

>>> from datetime import date >>> utc_date = date(2008, 1, 1) >>> timestamp = (utc_date.toordinal() - date(1970, 1, 1).toordinal()) * 24*60*60 1199145600

Ver más detalles en Convertir datetime.date a UTC timestamp en Python .


Siento que la respuesta principal aún no es tan clara, y vale la pena tomarse el tiempo para comprender el tiempo y las zonas horarias .

¡Lo más importante para entender cuando se trata de tiempo es que el tiempo es relativo !

  • 2017-08-30 13:23:00 : (una fecha inocente), representa una hora local en algún lugar del mundo, pero tenga en cuenta que 2017-08-30 13:23:00 en Londres NO 2017-08-30 13:23:00 AL MISMO TIEMPO que 2017-08-30 13:23:00 en San Francisco.

Debido a que la misma cadena de tiempo se puede interpretar como diferentes puntos en el tiempo dependiendo de dónde se encuentre en el mundo, existe la necesidad de una noción absoluta de tiempo.

Una marca de tiempo UTC es un número en segundos (o milisegundos) desde Epoch (definido como 1 January 1970 00:00:00 en la zona horaria GMT +00: 00 de desplazamiento).

La época está anclada en la zona horaria GMT y, por lo tanto, es un punto absoluto en el tiempo. Una marca de tiempo UTC que es un desplazamiento de un tiempo absoluto, por lo tanto, define un punto absoluto en el tiempo .

Esto hace posible ordenar eventos a tiempo.

Sin información de zona horaria, el tiempo es relativo y no puede convertirse en una noción absoluta de tiempo sin proporcionar alguna indicación de a qué zona horaria debe estar anclada la fecha y hora naive.

¿Cuáles son los tipos de tiempo utilizados en el sistema informático?

  • Naive datetime : normalmente para mostrar, en la hora local (es decir, en el navegador) donde el sistema operativo puede proporcionar información de zona horaria al programa.

  • Marcas de tiempo UTC : una marca de tiempo UTC es un punto absoluto en el tiempo, como se mencionó anteriormente, pero está anclado en una zona horaria determinada, por lo que una marca de tiempo UTC se puede convertir a una fecha y hora en cualquier zona horaria, sin embargo, no contiene información de zona horaria. Qué significa eso? Eso significa que 1504119325 corresponde a 2017-08-30T18:55:24Z , o 2017-08-30T17:55:24-0100 o también 2017-08-30T10:55:24-0800 . No te dice de dónde viene la fecha y hora grabada. Por lo general, se usa en el lado del servidor para registrar eventos (registros, etc.) o se usa para convertir un horario de tiempo con reconocimiento de zona horaria en un punto de tiempo absoluto y calcular las diferencias de tiempo .

  • Cadena de fecha y hora de ISO-8601 : ISO-8601 es un formato estandarizado para registrar la fecha y hora con la zona horaria. (De hecho, hay varios formatos, siga leyendo aquí: https://en.wikipedia.org/wiki/ISO_8601 ). Se utiliza para comunicar la información de fecha y hora de la zona horaria de manera serializable entre los sistemas.

¿Cuándo usar qué? o más bien, ¿cuándo necesitas preocuparte por los husos horarios?

  • Si necesita de alguna manera preocuparse por la hora del día , necesita información de la zona horaria. Un calendario o alarma necesita una hora del día para establecer una reunión a la hora correcta del día para cualquier usuario en el mundo. Si estos datos se guardan en un servidor, el servidor necesita saber a qué zona horaria corresponde la fecha y hora.

  • Para calcular las diferencias de tiempo entre eventos provenientes de diferentes lugares del mundo, la marca de tiempo UTC es suficiente, pero pierde la capacidad de analizar a qué hora del día se producen los eventos (es decir, para análisis web, es posible que desee saber cuándo los usuarios acceden a su sitio en su horario local : ¿ves más usuarios por la mañana o por la noche? No se puede resolver sin información del momento del día.

Offset de zona horaria en una cadena de fecha :

Otro punto que es importante es que el desplazamiento de la zona horaria en una cadena de fecha no es fijo . Eso significa que porque 2017-08-30T10:55:24-0800 dice que el offset -0800 u 8 horas atrás, ¡no significa que siempre lo será!

En el verano bien puede ser en horario de verano, y sería -0700

Lo que eso significa es que el desplazamiento de la zona horaria (+0100) no es lo mismo que el nombre de la zona horaria (Europa / Francia) o incluso la designación de la zona horaria (CET)

America/Los_Angeles zona horaria de America/Los_Angeles es un lugar en el mundo , pero se convierte en la notación de compensación de zona horaria PST (hora estándar del Pacífico) en el invierno y PDT (hora del Pacífico) en verano.

Entonces, además de obtener el desplazamiento de la zona horaria de la cadena de fechas, también debe obtener el nombre de la zona horaria para ser preciso.

La mayoría de los paquetes podrán convertir los desplazamientos numéricos del horario de verano al horario estándar por sí solos, pero eso no es necesariamente trivial con solo compensación. Por ejemplo, designación de zona horaria WAT en África occidental, UTC + 0100 es como la zona horaria CET en Francia, pero Francia observa el horario de verano, mientras que África occidental no (porque están cerca del ecuador)

Entonces, en resumen, es complicado. MUY complicado, y es por eso que no deberías hacer esto tú mismo, sino confiar en un paquete que lo haga por ti, ¡y MANTENGALO ACTUALIZADO!


También tenga en cuenta la función calendar.timegm() como se describe en this entrada de blog:

import calendar calendar.timegm(utc_timetuple)

La salida debe estar de acuerdo con la solución de vaab.


¿Qué es una datetime ingenua?

Se dice que los objetos predeterminados de datetime son "ingenuos": mantienen la información del tiempo sin la información de la zona horaria. Piense en datetime ingenuo como un número relativo (es decir: +4 ) sin un origen claro (de hecho, su origen será común a lo largo de los límites de su sistema). Piense en datetime enterado como números absolutos (es decir: 8 ) con un origen común para todo el mundo.

Sin la información de zona horaria no puede convertir el horario "ingenuo" a una representación de tiempo no ingenua (¿dónde hace +4 objetivos si no sabemos por dónde empezar?). Es por eso que no puede tener un método datetime.datetime.toutctimestamp() . (cf: http://bugs.python.org/issue1457227 )

Para comprobar si su datetime dt es ingenuo, compruebe dt.tzinfo , si None , entonces es ingenuo:

datetime.now() ## DANGER: returns naïve datetime pointing on local time datetime(1970, 1, 1) ## returns naïve datetime pointing on user given time

Tengo fechas pretéritas, ¿qué puedo hacer?

Debe hacer una suposición según su contexto particular: la pregunta que debe hacerse es: ¿era su datetime de datetime en UTC? o era hora local?

  • Si usaba UTC (no tiene problemas):

    import calendar def dt2ts(dt): """Converts a datetime object to UTC timestamp naive datetime will be considered UTC. """ return calendar.timegm(dt.utctimetuple())

  • Si NO estabas usando UTC , bienvenido al infierno.

    datetime hacer que su datetime no sea ingenua antes de usar la función anterior, devolviéndole la zona horaria deseada.

    Necesitará el nombre de la zona horaria y la información acerca de si el horario de verano estuvo en vigencia al producir el tiempo de programación ingenuo del objetivo (se necesita la última información sobre el horario de verano para las cajas de esquina):

    import pytz ## pip install pytz mytz = pytz.timezone(''Europe/Amsterdam'') ## Set your timezone dt = mytz.normalize(mytz.localize(dt, is_dst=True)) ## Set is_dst accordingly

    Consecuencias de no proporcionar is_dst :

    No usar is_dst generará una hora incorrecta (y la marca de tiempo UTC) si se produjo la fecha y hora de destino mientras se colocaba un DST hacia atrás (por ejemplo, cambiando el horario de verano eliminando una hora).

    Proporcionar is_dst incorrecto is_dst , por supuesto, una hora incorrecta (y una indicación de fecha y hora UTC) solo en la superposición DST o en los agujeros. Y, al proporcionar también el tiempo incorrecto, que ocurre en "agujeros" (tiempo que nunca existió debido al desplazamiento hacia adelante DST), is_dst dará una interpretación de cómo considerar este tiempo falso, y este es el único caso donde .normalize(..) realmente hará algo aquí, ya que luego lo traducirá como un tiempo válido real (cambiando el datetime Y el objeto DST si es necesario). Tenga en cuenta que .normalize() no es necesario para tener una marca de tiempo UTC correcta al final, pero probablemente se recomienda si no le gusta la idea de tener tiempos falsos en sus variables, especialmente si reutiliza esta variable en otro lugar.

    y EVITE USAR EL SIGUIENTE : (cf: conversión de Datetime Timezone usando pytz )

    dt = dt.replace(tzinfo=timezone(''Europe/Amsterdam'')) ## BAD !!

    ¿Por qué? porque .replace() reemplaza ciegamente el tzinfo sin tener en cuenta el tiempo objetivo y elegirá un objeto DST incorrecto. Mientras que .localize() usa el tiempo objetivo y su sugerencia de is_dst para seleccionar el objeto DST correcto.

ANTIGUA respuesta incorrecta (gracias @JFSebastien por mencionar esto):

Afortunadamente, es bastante fácil adivinar la zona horaria (su origen local) cuando crea su objeto naive datetime ya que está relacionado con la configuración del sistema que, ojalá, NO cambie entre la creación de objetos naive datetime y el momento en que desea obtener la marca de tiempo UTC. Este truco se puede utilizar para dar una pregunta imperfecta .

Al usar time.mktime podemos crear un utc_mktime :

def utc_mktime(utc_tuple): """Returns number of seconds elapsed since epoch Note that no timezone are taken into consideration. utc tuple must be: (year, month, day, hour, minute, second) """ if len(utc_tuple) == 6: utc_tuple += (0, 0, 0) return time.mktime(utc_tuple) - time.mktime((1970, 1, 1, 0, 0, 0, 0, 0, 0)) def datetime_to_timestamp(dt): """Converts a datetime object to UTC timestamp""" return int(utc_mktime(dt.timetuple()))

Debe asegurarse de que su objeto datetime se crea en la misma zona horaria que la que ha creado su datetime y datetime .

Esta última solución es incorrecta porque supone que el desplazamiento UTC a partir de ahora es el mismo que el desplazamiento UTC de EPOCH. Lo cual no es el caso para muchas zonas horarias (en el momento específico del año para las compensaciones del horario de verano (DST)).