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.fromtimestamptengo datetime.datetime(2013, 9, 1, 6, 0).
La hora no coincide. ¿Qué extrañé aquí?

timestampmé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.dtviene ¿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
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 en
utcfromtimestamplugar 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
timestampmé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
dtestá 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.pytzpodría usarse en este caso.pytzno 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 unapytzzona horaria y / o busque por nombre.tzlocalmódulo que también funciona en Windows. Así es como puede convertir la hora utc a la hora local .la solución es
fuente
des 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.%sno funciona en sistemas Windows (ValueError: Invalid format string)8o9En 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
%senstrftime. Esto es lo que encontré:En la fuente de Python para
datetimeytime, la cadenaSTRFTIME_FORMAT_CODESnos dice:Así que ahora si
man strftime(en sistemas BSD como Mac OS X), encontrará soporte para%s:De todos modos, por eso
%sfunciona 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.strftimedelegado de documentación a las plataformasstrftime(3)de función para directivas no compatibles.%spuede fallar incluso en Mac OS X, por ejemplo, datetime.strftime ('% s') debe respetar tzinfo .%sya 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)
arrowel 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.mktimesolo para dt local. El usocalendar.timegmes 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