w3schools - python datetime to timestamp
Python: Convertir la tupla de tiempo UTC en la marca de tiempo UTC (1)
Hay efectivamente solo tres valores diferentes. Estos dos valores:
1363425449.0 (time.mktime(datetime.timetuple(now))
1363425442 (cal.timegm(datetime.timetuple(utc_now)))
solo difiere en 7 segundos, que es lo que vio originalmente cuando volcó las variables:
>>> utc_now
datetime.datetime(2013, 3, 16, 9, 17, 22, 489225)
>>> now
datetime.datetime(2013, 3, 16, 5, 17, 29, 736903)
(Tenga en cuenta los 22 vs 29 en la parte de segundos de la salida.)
Los otros dos valores son simplemente erróneos, porque está aplicando el tipo incorrecto de argumentos: está llamando a time.mktime
con valores UTC en lugar de valores locales, y está llamando a cal.timegm
con valores locales en lugar de valores UTC. La documentación dice claramente lo que se espera, así que asegúrese de usar solo los valores apropiados. Básicamente, se ve que la diferencia de hora local (4 horas, según su aspecto) se aplica cuando no debería ser (en diferentes direcciones, dependiendo de dónde se encuentre el error).
Cuando está diagnosticando cosas como esta, es útil usar epochconverter.com que le dará la marca de tiempo actual de Unix, para que pueda compararla con su salida.
Mi problema: necesito convertir una tupla de tiempo UTC en una marca de tiempo UTC. Pero tengo algunas confusiones.
Primero un poco de información:
time.mktime(tuple)
: esta función siempre devuelve la marca de tiempo en hora local .Esta es la función inversa de localtime (). Su argumento es struct_time o full-9-tuple que expresa la hora en hora local, no UTC.
calendar.timegm(tuple)
: devuelve la marca de tiempo UTC de la tupla de tiempo suministradatoma una tupla de tiempo, como la que devuelve la función gmtime () en el módulo de tiempo, y devuelve el valor de marca de tiempo de Unix correspondiente. De hecho, time.gmtime () y timegm () son inversos de cada uno
Ahora vamos a hacer una prueba:
>>> from datetime import datetime
>>> import time
>>> import calendar as cal
>>> utc_now = datetime.utcnow()
>>> now = datetime.now()
>>> utc_now
datetime.datetime(2013, 3, 16, 9, 17, 22, 489225)
>>> now
datetime.datetime(2013, 3, 16, 5, 17, 29, 736903)
>>> time.mktime(datetime.timetuple(utc_now)), time.mktime(datetime.timetuple(now))
(1363439842.0, 1363425449.0)
>>> cal.timegm(datetime.timetuple(utc_now)), cal.timegm(datetime.timetuple(now))
(1363425442, 1363411049)
¿Por qué hay cuatro valores diferentes? ¿Y cuál es correcto cuando quiero convertir una tupla de tiempo UTC en una marca de tiempo UTC?
ACTUALIZAR
Creo que he encontrado respuestas a mis confusiones, así que déjame explicarte.
Primero, necesitamos saber algo importante:
Hay dos tipos de objetos de fecha y hora: "ingenuo" y "consciente".
Un objeto consciente tiene suficiente conocimiento de los ajustes de tiempo algorítmicos y políticos aplicables, como la zona horaria y la información del horario de verano, para ubicarse en relación con otros objetos conscientes. Un objeto consciente se utiliza para representar un momento específico en el tiempo que no está abierto a la interpretación [1].
Un objeto ingenuo no contiene suficiente información para ubicarse de forma inequívoca en relación con otros objetos de fecha / hora. Si un objeto ingenuo representa la hora universal coordinada (UTC), la hora local o la hora en otra zona horaria depende exclusivamente del programa, al igual que depende del programa si un número en particular representa metros, millas o masa. Los objetos ingenuos son fáciles de entender y trabajar, a costa de ignorar algunos aspectos de la realidad.
Lo que obtenemos de datetime.utcnow()
o datetime.now()
son objetos "ingenuos". Esto significa que el objeto de datetime
que se devuelve no dice, de ninguna manera, nada sobre su hora local u hora UTC, solo representa "alguna vez". Simplemente encapsula información de fecha y hora (año, mes, día, hora, minutos, segundos, etc.). Es SU responsabilidad asociarlo con la noción de local o UTC.
Entonces, recuerde que un objeto de fecha y hora ingenuo solo representa "algún tiempo". La función datetime.now()
devuelve "algún tiempo" que es igual a su hora actual, y la función datetime.utcnow()
devuelve "algún tiempo" que es la hora actual en Greenwich England (que es lo que es UTC).
El "algo de tiempo" es solo un valor para la fecha y la hora. Y tenga en cuenta que en diferentes lugares de la tierra, el "algún tiempo" ocurre en diferentes momentos. Por ejemplo, si un valor de "algún tiempo" es el 1 de enero a las 10:30, entonces será la hora actual en Greenwich Inglaterra unas 5 horas ANTES de que se convierta en la hora actual en Nueva York.
Por lo tanto, podemos ver que hay dos cosas: un valor genérico de "algún tiempo", y la noción de que "algún tiempo" se convierte en la hora actual en diferentes ubicaciones en diferentes "épocas". (no hay juego de palabras aquí, sigue leyendo)
Ahora, vamos a definir primero qué es "época". Sabemos que "algún tiempo" es solo un valor genérico de tiempo. Entonces, la época es un "tiempo" que ocurrió en Greenwich Inglaterra, donde los valores de los parámetros son: January 1 1970, 00:00:00
.
Una "marca de tiempo" es no. De segundos que han transcurrido desde la época. Esto significa que la marca de tiempo era 0
cuando era el Jan 1, 1970, 00:00:00
en Greenwich Inglaterra. Pero la marca de tiempo fue de aprox. (5 * 60 * 60) cuando era el Jan 1, 1970, 00:00:00
en Nueva York.
>>> tt = datetime.timetuple(datetime(1970, 1, 1, 0, 0, 0))
>>> cal.timegm(tt)
0
Por lo tanto, podemos ver que el mismo valor "en algún momento" del Jan 1, 1970, 00:00:00
de Jan 1, 1970, 00:00:00
tiene diferentes marcas de tiempo cuando cambiamos de ubicación. Por lo tanto, cuando se habla de la marca de tiempo, también debe decir "con qué ubicación" se relaciona la marca de tiempo, y cuánto del este o el oeste está relacionada con Greenwich Inglaterra. Esa ubicación se expresa como una "zona horaria".
Ahora, cada sistema (computadora) tiene una zona horaria configurada, y todas las marcas de tiempo relacionadas con esa zona horaria se convierten efectivamente en "locales". La UTC es la referencia global.
Entonces, digamos que tiene un valor de X
para "algún tiempo" que se convierte en:
-
Y
marca de tiempo en su hora local -
Z
marca de tiempo en UTC
entonces esto significa que Y
no. Los segundos deberán transcurrir durante "algún tiempo" para convertirse en la hora actual en su ubicación y Z
no tendrá que pasar ningún segundo para que la hora actual en Greenwich Inglaterra se convierta en "algún tiempo".
Ahora, finalmente, volvamos a nuestras funciones mktime
y timegm
. Estos toman una tupla de tiempo, que es solo otra representación de "algún tiempo". Recuerde que les estamos pasando un tiempo ingenuo que no tiene ninguna noción de local o UTC.
Digamos que X
es una tupla de tiempo que representa un ingenuo "algún tiempo". Entonces
-
mktime(X)
devolverá el no. de segundos que tendrán que transcurrir para que su hora local actual se convierta en ese "tiempo", y -
timegm(X)
devolverá el número de segundos que tendrá que gastar para hacer que la hora actual de Greenwich England sea igual a "algún tiempo".
En el ejemplo anterior, now
y utc_now
representan ingenuo "algún tiempo", y cuando introducimos mktime
valores de "algún tiempo" en mktime
y timegm
, simplemente devuelven el no. de segundos que deben transcurrir para que las ubicaciones correspondientes (su ubicación y Greenwich England) tengan su hora actual como "alguna vez".
Finalmente, volviendo a mi problema: necesito convertir una tupla de tiempo UTC en una marca de tiempo UTC.
En primer lugar, no hay un concepto de "tupla de tiempo UTC", es solo "algún tiempo". Si necesito convertirlo a UTC, simplemente uso timegm
:
cal.timegm(datetime.timetuple(utc_now))
lo que me dará la marca de tiempo para la hora UTC actual (es decir, la hora actual en Greenwich, Inglaterra).