Conversión de la cadena DateTime de Python en milisegundos enteros

Me gustaría convertir una cadena de sello UTC TimeDate en un valor entero de milisegundos (es posible que deba ser una cantidad de 64 bits), para que ocupe menos espacio cuando se almacena en una columna de la base de datos mySQL. Esta cadena UTC se está generando desde otra biblioteca, y la almaceno como un tipo de GUID por usuario.

¿Puede datetime o dateutil convertir esto en un solo valor entero (como “milisegundos desde la época”)? ¿O tengo que hacerlo yo mismo?

Análisis utilizando este enfoque:

myDateTime = dateutil.parser.parse("2015-06-27T02:10:05.653000Z") print("Parsed datetime String is {0}, ordinal value is {1}".format(myDateTime, myDateTime.toordinal())) 

Da la salida:

 Parsed datetime String is 2015-06-27 02:10:05.652999+00:00, ordinal value is 735776 

… que solo da un valor ordinal para la fecha. Además, si tengo un tiempo con un número entero de 653 milisegundos, quiero que el objeto analizado sepa que tiene 653 milisegundos, no 652999.

[Editado siguiendo sugerencia en los comentarios]

Usando la respuesta de Ben Alpert a Cómo puedo convertir un objeto de fecha y hora a milisegundos desde la época (tiempo de Unix) en Python , podemos hacer lo siguiente:

 from datetime import datetime def unix_time(dt): epoch = datetime.utcfromtimestamp(0) delta = dt - epoch return delta.total_seconds() def unix_time_millis(dt): return int(unix_time(dt) * 1000) a = datetime.strptime("2015-06-27T02:10:05.653000Z", "%Y-%m-%dT%H:%M:%S.%fZ") unix_time_millis(a) 

devoluciones:

 1435371005653 

que es equivalente a: sábado, 27 de junio de 2015 02:10:05 GMT (como se esperaba)

También podemos usar .strftime('%s') datetime para obtener el tiempo de Unix, incluso milisegundos usando lo siguiente ( pero esto no se recomienda ):

 from decimal import Decimal int(Decimal(datetime.strptime("2015-06-27T02:10:05.653000Z", "%Y-%m-%dT%H:%M:%S.%fZ").strftime('%s.%f'))*1000) 

devoluciones:

 1435396205653 

equivalente a: sábado, 27 de junio de 2015 09:10:05 GMT (en mi Mac en San Diego; Nota : esto es 7 horas de descanso de lo que podríamos haber esperado).

JF Sebastian describe la causa del error en los comentarios del enlace anterior y en esta respuesta con respecto al .strftime('%s') . JF Sebastian señala que “no es compatible, no es portátil, puede producir silenciosamente un resultado incorrecto para un objeto datetime consciente, falla si la entrada está en UTC (como en la pregunta) pero la zona horaria local no es UTC”

Hay dos partes:

  • para convertir "2015-06-27T02:10:05.653000Z" en un objeto de fecha y hora, consulte ¿Cómo analizar la fecha con formato ISO en Python?

     import re from datetime import datetime utc_time = datetime(*map(int, re.findall(r'\d+', time_string)) 
  • para convertir la hora UTC en la marca de tiempo POSIX como milisegundos enteros, consulte ¿Cómo puedo convertir un objeto de fecha y hora a milisegundos desde la época (hora de Unix) en Python?

     from datetime import datetime def timestamp_millis(utc_time, epoch=datetime(1970, 1, 1)): td = utc_time - epoch return (td.microseconds + (td.seconds + td.days * 86400) * 10**6) // 10**3 

Tanto Scott como GordonLinoff brindaron una excelente ayuda para resolver mi problema. Estoy agregando la respuesta para la integridad.

Código de Python para convertir la cadena de fecha y hora UTC a milisegundos desde la época:

EDITADO PARA ELIMINAR strftime:

 from datetime import datetime def convert_UTC_zulu_string_to_milliseconds_since_epoch(myUTCzuluString): try: dt_unix = datetime.strptime(myUTCzuluString, "%Y-%m-%dT%H:%M:%S.%fZ") epoch = datetime.utcfromtimestamp(0) delta = dt_unix - epoch millisecondsSinceEpoch = long(delta.total_seconds() * 1000) except: millisecondsSinceEpoch = 0L return millisecondsSinceEpoch myUTCzuluString = "2015-06-27T02:10:05.653000Z" millisecondsSinceEpoch = convert_UTC_zulu_string_to_milliseconds_since_epoch(myUTCzuluString) print("Milliseconds since epoch: {0}".format(millisecondsSinceEpoch)) 

TAMBIÉN: mysql aceptará un valor de fecha y hora con milisegundos / microsegundos directamente de una cadena SI he definido la columna como un tipo de datos DATETIME (6):

 UPDATE myTable SET myDateTimeField = '2015-06-27T02:10:05.653000Z' 

Tenga en cuenta que incluir la “Z” al final de la cadena de fecha y hora UTC da como resultado una advertencia de truncamiento de mysql.

No pude determinar si la precisión agregada de DATETIME (6) sobre DATETIME resultó en que el motor InnoDB de mysql usara más de 8 bytes, lo cual fue una de las razones iniciales para investigar el problema.