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()
, 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é extrañé aquí?
timestamp
método en lugar de intentar hacerlo usted mismo. Por un lado, eso evita por completo la posibilidad de restar tiempos ingenuos de diferentes zonas horarias.dt
viene ¿Es la hora local o la hora en UTC?Respuestas:
Lo que te perdiste aquí son las zonas horarias.
Presumiblemente tiene cinco horas fuera de UTC, así que 2013-09-01T11: 00: 00 local y 2013-09-01T06: 00: 00Z son la misma hora.
Debe leer la parte superior de los
datetime
documentos, 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 en
utcfromtimestamp
lugar defromtimestamp
.Por otro lado, si su fecha y hora ingenua original era local, no debería haberle sustraído 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, debe usar una época local (consciente) en ambos lados o convertirlo explícitamente desde y hacia UTC.
Si tiene, o puede actualizar a, Python 3.3 o posterior, puede evitar todos estos problemas simplemente usando el
timestamp
método en lugar de tratar de 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 es probable que llegue a la versión final, lo que significa que todas las cosas de las que hablamos JF Sebastian y yo en los comentarios deberían ser factibles solo con stdlib, y trabajando de la misma manera en Unix y Windows).
fuente
dt
está en la zona horaria local, entonces la fórmula en la pregunta es incorrectadatetime.fromtimestamp(0)
(epoch en la zona horaria actual) debe usarse en lugar dedatetime(1970, 1,1)
(epoch unix en UTC).fromtimestamp(0)
podría fallar si el sistema no almacena información histórica de zona horaria, por ejemplo, en Windows.pytz
podría usarse en este caso.pytz
no ayuda a menos que ya sepas en qué zona horaria estás; para hacerlo mediante programación, necesita una biblioteca diferente que obtenga la zona horaria actual de Windows y la convierta en unapytz
zona horaria y / o busque por nombre.tzlocal
módulo que también funciona en Windows. Así es como puede convertir la hora utc a la hora local .la solución es
fuente
d
es un objeto ingenuo de fecha / fecha y hora que representa la hora local (puede fallar para tiempos ambiguos o para fechas pasadas / futuras si el sistema operativo no proporciona un tz db histórico (el desplazamiento UTC podría haber sido diferente en el pasado en el local) zona horaria)). Más opciones .Si desea convertir una fecha y hora de Python a segundos desde época, debe hacerlo explícitamente:
En Python 3.3+ puedes usar
timestamp()
en su lugar:fuente
%s
, ya que estará localizado en el reloj del sistema en el que se encuentra actualmente. Solo debe usar.timestamp()
para obtener la hora correcta de Epoch / UNIX.%s
no funciona en sistemas Windows (ValueError: Invalid format string
)8
o9
En lugar de esta expresión para crear una marca de tiempo POSIX
dt
,Utilizar este:
Recibo la respuesta correcta en su ejemplo usando el segundo método.
EDIT: Algunas seguimiento ... Después de algunos comentarios (véase más adelante), tenía curiosidad acerca de la falta de apoyo o documentación
%s
enstrftime
. Esto es lo que encontré:En la fuente de Python para
datetime
ytime
, la cadenaSTRFTIME_FORMAT_CODES
nos dice:Así que ahora si
man strftime
(en sistemas BSD como Mac OS X), encontrará soporte para%s
:De todos modos, por eso
%s
funciona en los sistemas que lo hace. Pero hay mejores soluciones para el problema de OP (que tienen en cuenta las zonas horarias). Ver la respuesta aceptada de @ abarnert aquí.fuente
strftime("%s")
en la documentación, acabo de confirmar que funcione en Mac y Linux. Gracias.time.strftime()
ydatetime.strftime
delegado de documentación a las plataformasstrftime(3)
de función para directivas no compatibles.%s
puede fallar incluso en Mac OS X, por ejemplo, datetime.strftime ('% s') debe respetar tzinfo .%s
ya que solo usará la hora localizada del sistema en el que se encuentra. Desea usar.timestamp()
si está intentando obtener la marca de tiempo UNIX real.Para trabajar con zonas horarias UTC:
fuente
Te has perdido la información de zona horaria (ya contestada, de acuerdo)
arrow
el paquete permite evitar esta tortura con fecha y hora; Ya está escrito, probado, publicado en pypi, cross-python (2.6 - 3.xx).Todo lo que necesitas:
pip install arrow
(o agregar a las dependencias)Solución para tu caso
fuente
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:
fuente
Bueno, al convertir la marca de tiempo de TO unix, python básicamente asume UTC, pero al volver a convertir le dará una fecha convertida a su zona horaria local.
Ver esta pregunta / respuesta; Obtener zona horaria utilizada por datetime.datetime.fromtimestamp ()
fuente
Si desea la marca de tiempo UTC:
time.mktime
solo para dt local. El usocalendar.timegm
es seguro pero debe ser la zona utc, así que cambie la zona a utc. Si dt en UTC solo usecalendar.timegm
.fuente
fuente
Esta clase cubrirá sus necesidades, puede pasar la variable a ConvertUnixToDatetime y llamar a qué función desea que opere en función de.
fuente