Convierta fecha y hora a marca de tiempo Unix y vuelva a convertirla en Python

Resuelto kun asked hace 10 años • 12 respuestas

Tengo dt = datetime(2013,9,1,11)y me gustaría obtener una marca de tiempo Unix de este objeto de fecha y hora.

Cuando lo hago, (dt - datetime(1970,1,1)).total_seconds()obtengo la marca de tiempo 1378033200.

Al volver a convertirlo usando datetime.fromtimestampobtuve datetime.datetime(2013, 9, 1, 6, 0).

La hora no coincide. ¿Qué me perdí aquí?

kun avatar Nov 06 '13 07:11 kun
Aceptado

la solución es

import time
import datetime
d = datetime.date(2015,1,5)

unixtime = time.mktime(d.timetuple())
DmitrySemenov avatar Jan 13 '2015 03:01 DmitrySemenov

Si desea convertir una fecha y hora de Python a segundos desde la época, debe hacerlo explícitamente:

>>> import datetime
>>> datetime.datetime(2012, 04, 01, 0, 0).strftime('%s')
'1333234800'
>>> (datetime.datetime(2012, 04, 01, 0, 0) - datetime.datetime(1970, 1, 1)).total_seconds()
1333238400.0

En Python 3.3+ puedes usar timestamp()en su lugar:

>>> import datetime
>>> datetime.datetime(2012, 4, 1, 0, 0).timestamp()
1333234800.0
Francisco Costa avatar Jan 23 '2017 17:01 Francisco Costa

Lo que te perdiste aquí son las zonas horarias.

Presumiblemente tienes cinco horas fuera de UTC, por lo que 2013-09-01T11:00:00 local y 2013-09-01T06:00:00Z son la misma hora.

Debe leer la parte superior de los datetimedocumentos, que explican las zonas horarias y los objetos "ingenuos" y "conscientes".

Si su fecha y hora ingenua original era UTC, la forma de recuperarla es usarla utcfromtimestampen lugar de fromtimestamp.

Por otro lado, si su fecha y hora ingenua original era local, no debería haberle restado una marca de tiempo UTC en primer lugar; utilizar datetime.fromtimestamp(0)en su lugar.

O, si tenía un objeto de fecha y hora consciente, necesita usar una época local (consciente) en ambos lados o convertir explícitamente hacia y desde UTC.

Si tiene Python 3.3 o posterior, o puede actualizarlo, puede evitar todos estos problemas simplemente usando el timestampmétodo en lugar de intentar descubrir cómo hacerlo usted mismo. E incluso si no lo hace, puede considerar tomar prestado su código fuente .

(Y si puede esperar a Python 3.4, parece que PEP 341 probablemente llegue a la versión final, lo que significa que todo lo que JF Sebastian y yo estábamos hablando en los comentarios debería poder realizarse solo con stdlib, y funciona de la misma manera tanto en Unix como en Windows).

abarnert avatar Nov 06 '2013 00:11 abarnert

En lugar de esta expresión para crear una marca de tiempo POSIX dt,

(dt - datetime(1970,1,1)).total_seconds()

Utilizar esta:

int(dt.strftime("%s"))

Obtengo la respuesta correcta en su ejemplo usando el segundo método.

EDITAR: Algo de seguimiento... Después de algunos comentarios (ver más abajo), tenía curiosidad por la falta de soporte o documentación para %sin strftime. Esto es lo que encontré:

En la fuente de Python para datetimey time, la cadena STRFTIME_FORMAT_CODESnos dice:

"Other codes may be available on your platform.
 See documentation for the C library strftime function."

Ahora, si man strftime(en sistemas BSD como Mac OS X), encontrará soporte para %s:

"%s is replaced by the number of seconds since the Epoch, UTC (see mktime(3))."

De todos modos, es por eso que %sfunciona en los sistemas que lo hace. Pero existen mejores soluciones al problema de OP (que tienen en cuenta las zonas horarias). Vea la respuesta aceptada de @abarnert aquí.

Darren Stone avatar Nov 06 '2013 00:11 Darren Stone