create - Convierta datetime a Unix timestamp y conviértalo nuevamente en python
timedelta python example (8)
Bueno, al convertir a la marca de tiempo UNix, python básicamente está asumiendo el UTC, pero al convertir de nuevo le dará una fecha convertida a su zona horaria local.
Ver esta pregunta / respuesta; Obtenga la zona horaria utilizada por datetime.datetime.fromtimestamp ()
Tengo dt = datetime(2013,9,1,11)
, y me gustaría obtener una marca de tiempo Unix de este objeto datetime.
Cuando lo hago dt - datetime(1970,1,1)).total_seconds()
obtuve la marca de tiempo 1378033200
.
Al convertirlo de nuevo usando datetime.fromtimestamp
obtuve datetime.datetime(2013, 9, 1, 6, 0)
.
La hora no coincide. ¿Qué extrañé aquí?
En lugar de esta expresión para crear una marca de tiempo POSIX de dt
,
(dt - datetime(1970,1,1)).total_seconds()
Utilizar esta:
int(dt.strftime("%s"))
Obtuve la respuesta correcta en tu ejemplo usando el segundo método.
EDITAR: Algunos seguimientos ... Después de algunos comentarios (ver a continuación), tenía curiosidad acerca de la falta de soporte o documentación para %s
en strftime
. Esto es lo que encontré:
En la fuente de Python para datetime
y time
, la cadena STRFTIME_FORMAT_CODES
nos dice:
"Other codes may be available on your platform.
See documentation for the C library strftime function."
Así que ahora si tenemos tiempo de 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 %s
funciona en los sistemas que hace. Pero hay mejores soluciones para el problema de OP (que tienen en cuenta las zonas horarias). Vea la respuesta aceptada de @ abarnert aquí.
Lo que te perdiste aquí son los husos horarios.
Es de suponer que tiene cinco horas fuera de UTC, por lo que 2013-09-01T11: 00: 00 local y 2013-09-01T06: 00: 00Z son al mismo tiempo.
Necesita leer la parte superior de los documentos de datetime
, que explican sobre las zonas horarias y los objetos "ingenuos" y "conscientes".
Si su fecha de fromtimestamp
ingenua original fue UTC, la forma de recuperarla es usar utcfromtimestamp
lugar de fromtimestamp
.
Por otro lado, si tu fecha original original era local, no debiste haber restado una marca de tiempo UTC de ella en primer lugar; use datetime.fromtimestamp(0)
lugar.
O bien, si tiene un objeto datetime al tanto, necesita usar un epoch local (aware) en ambos lados o convertir explícitamente a UTC.
Si tiene, o puede actualizar a, Python 3.3 o posterior, puede evitar todos estos problemas simplemente usando el método de timestamp
lugar de tratar de averiguar cómo hacerlo usted mismo. E incluso si no lo hace, es posible que desee considerar tomar prestado su código fuente .
(Y si puedes esperar a Python 3.4, parece que PEP 341 probablemente llegue a la versión final, lo que significa que todas las cosas de las que JF Sebastian y yo estábamos hablando en los comentarios deberían ser factibles solo con stdlib, y trabajando de la misma manera tanto en Unix como en Windows).
Si desea convertir una fecha y hora de python en segundos desde epoch, 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()
lugar:
>>> import datetime
>>> datetime.datetime(2012,4,1,0,0).timestamp()
1333234800.0
Si su objeto datetime representa la hora UTC, no use time.mktime, ya que supone que la tupla está en su zona horaria local. En su lugar, use calendar.timegm:
>>> import datetime, calendar
>>> d = datetime.datetime(1970, 1, 1, 0, 1, 0)
>>> calendar.timegm(d.timetuple())
60
Te perdiste la información de la zona horaria (ya respondiste, aceptaste)
arrow
paquete de arrow
permite evitar esta tortura con las fechas; Ya está escrito, probado, pypi-publicado, cross-python (2.6 - 3.xx).
Todo lo que necesita: pip install arrow
(o agregar a dependencias)
Solución para su caso
dt = datetime(2013,9,1,11)
arrow.get(dt).timestamp
# >>> 1378033200
bc = arrow.get(1378033200).datetime
print(bc)
# >>> datetime.datetime(2013, 9, 1, 11, 0, tzinfo=tzutc())
print(bc.isoformat())
# >>> ''2013-09-01T11:00:00+00:00''
la solución es
import time
import datetime
d = datetime.date(2015,1,5)
unixtime = time.mktime(d.timetuple())
def dt2ts(dt):
import calendar
import time
from dateutil import tz
if dt.tzinfo is None:
return int(time.mktime(dt.timetuple()))
utc_dt = dt.astimezone(tz.tzutc()).timetuple()
return calendar.timegm(utc_dt)
Si desea la marca de tiempo UTC: time.mktime
solo para dt local. Use calendar.timegm
es seguro, pero dt debe ser la zona utc para cambiar la zona a utc