Python: Convertir cadena a marca de tiempo con microsegundos

Me gustaría convertir el formato de fecha de cadena a la marca de tiempo con microsegundos. Intento lo siguiente pero no doy el resultado esperado:

"""input string date -> 2014-08-01 04:41:52,117 expected result -> 1410748201.117""" import time import datetime myDate = "2014-08-01 04:41:52,117" timestamp = time.mktime(datetime.datetime.strptime(myDate, "%Y-%m-%d %H:%M:%S,%f").timetuple()) print timestamp > 1410748201.0 

¿A dónde se fueron los milisegundos?

No hay ranura para el componente de microsegundos en una tupla de tiempo:

 >>> import time >>> import datetime >>> myDate = "2014-08-01 04:41:52,117" >>> datetime.datetime.strptime(myDate, "%Y-%m-%d %H:%M:%S,%f").timetuple() time.struct_time(tm_year=2014, tm_mon=8, tm_mday=1, tm_hour=4, tm_min=41, tm_sec=52, tm_wday=4, tm_yday=213, tm_isdst=-1) 

Tendrás que agregarlos manualmente:

 >>> dt = datetime.datetime.strptime(myDate, "%Y-%m-%d %H:%M:%S,%f") >>> time.mktime(dt.timetuple()) + (dt.microsecond / 1000000.0) 1406864512.117 

El otro método que podría seguir es producir un objeto timedelta() relativo a la época, luego obtener la marca de tiempo con el método timedelta.total_seconds() :

 epoch = datetime.datetime.fromtimestamp(0) (dt - epoch).total_seconds() 

El uso de una época de tiempo local es bastante deliberado, ya que tiene un valor de fecha y hora ingenuo (que no tiene en cuenta la zona horaria). Este método puede ser inexacto según el historial de su zona horaria local; sin embargo, vea el comentario de JF Sebastian . Tendría que convertir el valor de fecha y hora ingenuo en un valor de fecha y hora compatible con la zona horaria utilizando primero su zona horaria local antes de restar una época compatible con la zona horaria.

Como tal, es más fácil seguir el timetuple() + microsegundos.

Manifestación:

 >>> dt = datetime.datetime.strptime(myDate, "%Y-%m-%d %H:%M:%S,%f") >>> epoch = datetime.datetime.fromtimestamp(0) >>> (dt - epoch).total_seconds() 1406864512.117 

¿A dónde se fueron los milisegundos?

Es la parte fácil. .timetuple() llama a .timetuple() . Puede volver a .microsecond usando el atributo .microsecond . El método datetime.timestamp() de la biblioteca estándar funciona de esa manera para los objetos de fecha y hora ingenuos:

 def timestamp(self): "Return POSIX timestamp as float" if self._tzinfo is None: return _time.mktime((self.year, self.month, self.day, self.hour, self.minute, self.second, -1, -1, -1)) + self.microsecond / 1e6 else: return (self - _EPOCH).total_seconds() 

Es suficiente si es posible ~ 1 hora de errores podrían ser ignorados en su caso. Supongo que desea microsegundos y, por lo tanto, no puede ignorar ~ 1 hora de errores en silencio.

Convertir la hora local dada como una cadena a la marca de tiempo POSIX correctamente es una tarea compleja en general. Puede convertir la hora local a UTC y luego obtener la marca de hora de la hora UTC .

Hay dos cuestiones principales:

  • la hora local puede ser inexistente o ambigua, por ejemplo, durante las transiciones DST, la misma hora puede ocurrir dos veces
  • El desplazamiento UTC para la zona horaria local puede ser diferente en el pasado y, por lo tanto, es ingenuo: local time minus epoch in local time fórmula de la local time minus epoch in local time puede fallar

Ambos se pueden resolver utilizando la base de datos tz (módulo pytz en Python):

 from datetime import datetime import pytz # $ pip install pytz from tzlocal import get_localzone # $ pip install tzlocal tz = get_localzone() # get pytz timezone corresponding to the local timezone naive_d = datetime.strptime(myDate, "%Y-%m-%d %H:%M:%S,%f") # a) raise exception for non-existent or ambiguous times d = tz.localize(naive_d, is_dst=None) ## b) assume standard time, adjust non-existent times #d = tz.normalize(tz.localize(naive_d, is_dst=False)) ## c) assume DST is in effect, adjust non-existent times #d = tz.normalize(tz.localize(naive_d, is_dst=True)) timestamp = d - datetime(1970, 1, 1, tzinfo=pytz.utc) 

El resultado es una timestamp : un objeto timedelta , puede convertirlo en segundos, milisegundos, etc.

También diferentes sistemas pueden comportarse de manera diferente alrededor de / durante segundos de salto. La mayoría de las aplicaciones pueden ignorar que existen.

En general, podría ser más sencillo almacenar las marcas de tiempo POSIX además de la hora local en lugar de intentar adivinarlo a partir de la hora local.

En Python 3.4 y posteriores puedes usar

 timestamp = datetime.datetime.strptime(myDate, "%Y-%m-%d %H:%M:%S,%f").timestamp() 

Esto no requiere importar el módulo de time . También usa menos pasos por lo que debería ser más rápido. Para versiones anteriores de python, las otras respuestas proporcionadas son probablemente su mejor opción.