¿Cómo se convierte un objeto time.struct_time en un objeto datetime?

288

¿Cómo se convierte un time.struct_timeobjeto Python en un datetime.datetimeobjeto?

Tengo una biblioteca que proporciona la primera y una segunda biblioteca que quiere la segunda.

static_rtti
fuente

Respuestas:

384

Use time.mktime () para convertir la tupla de tiempo (en localtime) en segundos desde la época, luego use datetime.fromtimestamp () para obtener el objeto datetime.

from datetime import datetime
from time import mktime

dt = datetime.fromtimestamp(mktime(struct))
Rod Hyde
fuente
45
Tenga en cuenta que esto falla antes de 1900. ¡Ustedes, los modernos, nunca recuerdan esta limitación!
mlissner
3
¿perderá esto los tm_isdstdatos? Creo que sí, dando como resultado la fecha y hora objeto permanece ingenua en la medida en que volver Nonea .dst()incluso si struct.tm_isdstes 1.
n611x007
3
Esto generalmente funcionará. Sin embargo, fallará si la tupla de tiempo está más allá de los valores que acepta mktime, por ejemplo para el valor (1970, 1, 1, 0, 0, 0, 0, 1, -1). Me he encontrado con esto después de analizar el encabezado Fecha en una solicitud HTTP que devolvió esta tupla.
user3820547
3
@richvdh: el estándar C especifica que se mktime()debe tener tm_isdsten cuenta y Python time.mktime()llama a la mktime()función C en CPython. mktime()puede elegir la hora local incorrecta cuando es ambigua (por ejemplo, durante la transición de fin de DST ("retroceso") si struct.tm_isdstes -1o si mktime()en la plataforma dada ignora la entrada tm_isdst . Además, si la zona horaria local tuvo una compensación de utc diferente en el pasado y C mktime()no utiliza una base de datos tz histórica que pueda proporcionar los valores de compensación de utc antiguos, también mktime()puede devolver un valor incorrecto (por ejemplo, por una hora).
jfs
1
@naxa: si mktime()no ignora tm_isdsten la plataforma dada (sí en la mía), fromtimestamp()definitivamente pierde la información: el objeto ingenuo devuelto datetimeque representa la hora local puede ser ambiguo (marca de tiempo -> la hora local es determinista (si ignoramos los segundos bisiestos) pero local time -> timestamp may be ambiguous e.g., during end-of-DST transition). Also, fromtimestamp () `puede elegir un desplazamiento utc incorrecto si no utiliza una base de datos tz histórica.
jfs
123

Me gusta esto:

>>> structTime = time.localtime()
>>> datetime.datetime(*structTime[:6])
datetime.datetime(2009, 11, 8, 20, 32, 35)
Nadia Alramli
fuente
3
No olvides # importar hora, fecha
# importar jhwist
77
@jhwist: algunas cosas en las que se puede confiar para que las personas lo resuelvan por sí mismas :)
orip
14
@rodling the *y **syntax le permite expandir un objeto de tipo listy o dicty para separar los argumentos: es una de mis piezas favoritas de Python. Ver docs.python.org/2/tutorial/… para más información
OrganicPanda
10
Solo recuerde que esto le dará un ValueError si el struct_time tiene un segundo de salto, por ejemplo:t=time.strptime("30 Jun 1997 22:59:60", "%d %b %Y %H:%M:%S"); datetime.datetime(*t[:6])
berdario
77
@berdario: para devolver valores compatibles con datetime: datetime(*t[:5]+(min(t[5], 59),))por ejemplo, para aceptar "2015-06-30 16:59:60 PDT".
jfs
37

Esta no es una respuesta directa a su pregunta (que ya se respondió bastante bien). Sin embargo, habiendo tenido momentos que me muerden varias veces, no puedo enfatizar lo suficiente como para que te incumba mirar de cerca lo que proporciona tu objeto time.struct_time, en comparación con los otros campos de tiempo que pueda tener.

Suponiendo que tiene un objeto time.struct_time y alguna otra cadena de fecha / hora, compare los dos y asegúrese de no perder datos y crear un objeto datetime ingenuo sin darse cuenta, cuando puede hacerlo de otra manera.

Por ejemplo, el excelente módulo feedparser devolverá un campo "publicado" y puede devolver un objeto time.struct_time en su campo "updated_parsed":

time.struct_time(tm_year=2013, tm_mon=9, tm_mday=9, tm_hour=23, tm_min=57, tm_sec=42, tm_wday=0, tm_yday=252, tm_isdst=0)

Ahora tenga en cuenta lo que realmente obtiene con el campo "publicado".

Mon, 09 Sep 2013 19:57:42 -0400

Por la barba de Stallman ! Información de zona horaria!

En este caso, el hombre perezoso podría querer usar el excelente módulo dateutil para mantener la información de la zona horaria:

from dateutil import parser
dt = parser.parse(entry["published"])
print "published", entry["published"])
print "dt", dt
print "utcoffset", dt.utcoffset()
print "tzinfo", dt.tzinfo
print "dst", dt.dst()

lo que nos da:

published Mon, 09 Sep 2013 19:57:42 -0400
dt 2013-09-09 19:57:42-04:00
utcoffset -1 day, 20:00:00
tzinfo tzoffset(None, -14400)
dst 0:00:00

Entonces se podría usar el objeto datetime con reconocimiento de la zona horaria para normalizar todo el tiempo a UTC o lo que sea que piense que es increíble.

lisdexia
fuente
77
Todos los *_parsedcampos de feedparsed ya están normalizados a UTC, como se puede verificar en la documentación de análisis de fechas, por lo que esto es redundante.
itorres
1
@itorres: si lo entiendo, esta respuesta no se trata de normalizar a UTC, sino de mantener la información de la zona horaria en un datetimeobjeto que se pierde al feedparseranalizar las fechas de cadena sin procesar.
davidag