web-dev-qa-db-fra.com

Comment analyser une chaîne temporelle contenant des millisecondes avec python?

Je suis capable d'analyser des chaînes contenant la date/heure avec time.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)

Comment analyser une chaîne temporelle contenant des millisecondes?

>>> 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
170
ilkinulas

Python 2.6 a ajouté une nouvelle macro strcode/strptime %f, qui effectue des microsecondes. Pas sûr si cela est documenté n'importe où. Mais si vous utilisez 2.6 ou 3.0, vous pouvez faire ceci:

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

Edit: je ne travaille jamais vraiment avec le module time, je ne l’avais donc pas remarqué au début, mais il semble que time.struct_time ne stocke pas réellement des millisecondes/microsecondes. Vous aurez peut-être intérêt à utiliser datetime, comme ceci:

>>> from datetime import datetime
>>> a = datetime.strptime('30/03/09 16:31:32.123', '%d/%m/%y %H:%M:%S.%f')
>>> a.microsecond
123000
262
DNS

Je sais que la question est ancienne, mais j'utilise toujours Python 2.4.3 et je devais trouver un meilleur moyen de convertir la chaîne de données en date-heure.

La solution si datetime ne prend pas en charge% f et sans avoir besoin de try/except est:

    (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 

Cela fonctionne pour la chaîne d'entrée "2010-10-06 09: 42: 52.266000"

12
Andrew Stern

Pour donner le code que la réponse de nstehr fait référence à (à partir de sa source ):

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
Phil H

Pour Python 2 je l'ai fait

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

il affiche le temps "% H:% M:% S", divise le temps.time () en deux sous-chaînes (avant et après le.) xxxxxxx.xx et .xx étant mes millisecondes, j'ajoute la deuxième sous-chaîne à mon "% H:% M:% S "

espérons que cela a du sens:) Exemple de sortie:

13: 31: 21.72 Clignote 01


13: 31: 21.81 FIN DE BLINK 01


13: 31: 26.3 Blink 01


13: 31: 26.39 FIN DE BLINK 01


13: 31: 34.65 Départ de la voie 01


1
Papatrexas

Ma première pensée a été d'essayer de passer '30/03/09 16: 31: 32.123 '(avec un point au lieu de deux points entre les secondes et les millisecondes.) Mais cela n'a pas fonctionné. Un rapide coup d'œil sur la documentation indique que les fractions de seconde sont ignorées dans tous les cas ...

Ah, différences de version. C'était rapporté comme un bogue et maintenant dans la version 2.6+, vous pouvez utiliser "% S.% f" pour l'analyser.

1
MarkusQ

depuis les listes de diffusion python: analyse du fil milliseconde . Il y a une fonction affichée à cet endroit qui semble faire le travail, bien que, comme mentionné dans les commentaires de l'auteur, c'est un peu un bidouillage. Il utilise des expressions régulières pour gérer l'exception qui est levée, puis effectue des calculs.

Vous pouvez également essayer de faire les expressions régulières et les calculs à l’avant, avant de les passer à strptime.

1
nstehr

La réponse DNS ci-dessus est en fait incorrecte. Le SO pose une question sur les millisecondes, mais la réponse concerne les microsecondes. Malheureusement, Python n'a pas de directive pour les millisecondes, mais seulement des microsecondes (voir doc ), mais vous pouvez contourner le problème en ajoutant trois zéros à la fin de la chaîne et en les analysant sous forme de microsecondes, comme suit:

datetime.strptime(time_str + '000', '%d/%m/%y %H:%M:%S.%f')

time_str est formaté comme 30/03/09 16:31:32.123.

J'espère que cela t'aides.

0
Rafid