Convertir datetime a marca de tiempo Unix y convertirlo de nuevo en python
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()
tengo la marca de tiempo 1378033200
.
Al convertirlo de nuevo usando datetime.fromtimestamp
tengo datetime.datetime(2013, 9, 1, 6, 0)
.
La hora no coincide. ¿Qué me perdí aquí?
9 answers
Lo que te perdiste aquí son 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.
Usted necesita leer la parte superior de la datetime
documentos, que explican sobre zonas horarias y objetos" ingenuos "y" conscientes".
Si su fecha y hora ingenua original era UTC, la forma de recuperarla es usar utcfromtimestamp
en lugar de fromtimestamp
.
Por otro lado, si su fecha y hora ingenua original era local, usted no debería haber restado una marca de tiempo UTC en primer lugar; use datetime.fromtimestamp(0)
en su lugar.
O, si tenía un objeto datetime consciente, necesita usar una época local (consciente) en ambos lados, o convertir explícitamente hacia y desde UTC.
Si usted tiene, o puede actualizar a, Python 3.3 o posterior, puede evitar todos estos problemas simplemente utilizando el timestamp
método en lugar de tratar de averiguar cómo hacerlo usted mismo. E incluso si no lo hace, es posible que desee considerar tomando prestado su código fuente.
(Y si puedes esperar a Python 3.4, parece que PEP 341 es probable que llegue a la versión final, lo que significa que todas las cosas de las que J. F. Sebastian y yo estábamos hablando en los comentarios deberían ser factibles solo con stdlib, y funcionar de la misma manera tanto en Unix como en Windows.)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-22 19:23:28
La Solución es
import time
import datetime
d = datetime.date(2015,1,5)
unixtime = time.mktime(d.timetuple())
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-13 03:21:47
En lugar de esta expresión para crear una marca de tiempo POSIX desde dt
,
(dt - datetime(1970,1,1)).total_seconds()
Usa esto:
int(dt.strftime("%s"))
Obtengo la respuesta correcta en tu ejemplo usando el segundo método.
EDITAR: Algún seguimiento... Después de algunos comentarios (ver más abajo), tenía curiosidad por la falta de apoyo 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 man strftime
(en BSD sistemas 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 lo hace. Pero hay mejores soluciones al problema de OP (que tienen en cuenta las zonas horarias). Vea la respuesta aceptada de @abarnert aquí.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-14 06:31:09
Si desea convertir una datetime de python a 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 + puede utilizar timestamp()
en su lugar:
>>> import datetime
>>> datetime.datetime(2012,4,1,0,0).timestamp()
1333234800.0
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-09 14:18:06
Si su objeto datetime representa la hora UTC, no use la hora.mktime, ya que asume que la tupla está en tu zona horaria local. En su lugar, utilice calendario.timegm:
>>> import datetime, calendar
>>> d = datetime.datetime(1970, 1, 1, 0, 1, 0)
>>> calendar.timegm(d.timetuple())
60
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-28 07:10:50
Bueno, cuando se convierte A la marca de tiempo unix, python básicamente asume UTC, pero mientras se convierte de nuevo le dará una fecha convertida a su zona horaria local.
Ver esta pregunta/respuesta; Obtener la zona horaria utilizada por datetime.datetime.fromestamp()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:45
Te has perdido la información de la zona horaria (ya respondida, de acuerdo)
arrow
package permite evitar esta tortura con datetimes; Ya está escrito, probado, pypi-published, cross-python (2.6 - 3.xx).
Todo lo que necesitas: pip install arrow
(o añadir 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'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-01 13:02:35
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 local dt .Use calendar.timegm
es seguro, pero dt debe la zona utc para cambiar la zona a utc
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-29 04:00:44
Para trabajar con zonas horarias UTC:
time_stamp = calendar.timegm(dt.timetuple())
datetime.utcfromtimestamp(time_stamp)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-25 16:51:07