¿Cómo puedo analizar una cadena de tiempo que contiene milisegundos con python?


Soy capaz de analizar cadenas que contienen fecha/hora con hora.strptime

>>> import time
>>> time.strptime('30/03/09 16:31:32', '%d/%m/%y %H:%M:%S')
(2009, 3, 30, 16, 31, 32, 0, 89, -1)

¿Cómo puedo analizar una cadena de tiempo que contiene milisegundos?

>>> time.strptime('30/03/09 16:31:32.123', '%d/%m/%y %H:%M:%S')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.5/_strptime.py", line 333, in strptime
    data_string[found.end():])
ValueError: unconverted data remains: .123
Author: Martin Thoma, 2009-03-30

6 answers

Python 2.6 agregó una nueva macro strftime/strptime %f, que hace microsegundos. No estoy seguro de si esto está documentado en algún lugar. Pero si estás usando 2.6 o 3.0, puedes hacer esto:

time.strptime('30/03/09 16:31:32.123', '%d/%m/%y %H:%M:%S.%f')

Editar: Realmente nunca trabajo con el módulo time, así que no me di cuenta de esto al principio, pero parece que esa vez.struct_time en realidad no almacena milisegundos / microsegundos. Puede ser mejor usar datetime, así:

>>> from datetime import datetime
>>> a = datetime.strptime('30/03/09 16:31:32.123', '%d/%m/%y %H:%M:%S.%f')
>>> a.microsecond
123000
 248
Author: DNS,
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
2011-08-02 07:59:09

Sé que esta es una pregunta antigua, pero todavía estoy usando Python 2.4.3 y necesitaba encontrar una mejor manera de convertir la cadena de datos a una datetime.

La solución si datetime no soporta %f y sin necesidad de probar / except es:

    (dt, mSecs) = row[5].strip().split(".") 
    dt = datetime.datetime(*time.strptime(dt, "%Y-%m-%d %H:%M:%S")[0:6])
    mSeconds = datetime.timedelta(microseconds = int(mSecs))
    fullDateTime = dt + mSeconds 

Esto funciona para la cadena de entrada"2010-10-06 09:42:52.266000"

 12
Author: Andrew Stern,
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
2010-10-12 15:09:19

Para dar el código al que la respuesta de nstehr se refiere (de su fuente):

def timeparse(t, format):
    """Parse a time string that might contain fractions of a second.

    Fractional seconds are supported using a fragile, miserable hack.
    Given a time string like '02:03:04.234234' and a format string of
    '%H:%M:%S', time.strptime() will raise a ValueError with this
    message: 'unconverted data remains: .234234'.  If %S is in the
    format string and the ValueError matches as above, a datetime
    object will be created from the part that matches and the
    microseconds in the time string.
    """
    try:
        return datetime.datetime(*time.strptime(t, format)[0:6]).time()
    except ValueError, msg:
        if "%S" in format:
            msg = str(msg)
            mat = re.match(r"unconverted data remains:"
                           " \.([0-9]{1,6})$", msg)
            if mat is not None:
                # fractional seconds are present - this is the style
                # used by datetime's isoformat() method
                frac = "." + mat.group(1)
                t = t[:-len(frac)]
                t = datetime.datetime(*time.strptime(t, format)[0:6])
                microsecond = int(float(frac)*1e6)
                return t.replace(microsecond=microsecond)
            else:
                mat = re.match(r"unconverted data remains:"
                               " \,([0-9]{3,3})$", msg)
                if mat is not None:
                    # fractional seconds are present - this is the style
                    # used by the logging module
                    frac = "." + mat.group(1)
                    t = t[:-len(frac)]
                    t = datetime.datetime(*time.strptime(t, format)[0:6])
                    microsecond = int(float(frac)*1e6)
                    return t.replace(microsecond=microsecond)

        raise
 3
Author: Phil H,
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 11:55:01

Mi primer pensamiento fue intentar pasarlo '30/03/09 16:31:32.123' (con un punto en lugar de dos puntos entre los segundos y los milisegundos. Pero eso no funcionó. Un vistazo rápido a los documentos indica que los segundos fraccionarios se ignoran en cualquier caso...

Ah, diferencias de versión. Esto fue reportado como un error y ahora en 2.6+ puede usar "%S.%f" para analizarlo.

 1
Author: MarkusQ,
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
2009-03-30 17:50:51

De las listas de correo de python: analizando el hilo en milisegundos. Hay una función publicada allí que parece hacer el trabajo, aunque como se menciona en los comentarios del autor es una especie de truco. Utiliza expresiones regulares para manejar la excepción que se eleva, y luego hace algunos cálculos.

También puede intentar hacer las expresiones regulares y los cálculos por adelantado, antes de pasarlo a strptime.

 1
Author: nstehr,
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-01-12 16:51:09

Para python 2 hice esto

print ( time.strftime("%H:%M:%S", time.localtime(time.time())) + "." + str(time.time()).split(".",1)[1])

Imprime el tiempo "%H:%M:%S" , divide el tiempo.tiempo() a dos subcadenas (antes y después de la .) xxxxxxx.xx y desde entonces .xx son mis milisegundos agrego la segunda subcadena a mi "%H:%M:%S"

Esperanza que tiene sentido :) Ejemplo de salida:

13:31:21.72 Blink 01


13:31:21.81 FIN DEL PARPADEO 01


13:31:26.3 Blink 01


13:31:26.39 FIN DEL PARPADEO 01


13:31:34.65 Carril de salida 01


 1
Author: Papatrexas,
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
2014-11-01 13:36:53