Wie kann ich eine Zeitzeichenfolge mit Millisekunden mit Python analysieren?

203

Ich kann Zeichenfolgen mit Datum / Uhrzeit mit time.strptime analysieren

>>> 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)

Wie kann ich eine Zeitzeichenfolge analysieren, die Millisekunden enthält?

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

Antworten:

316

Python 2.6 hat ein neues strftime / strptime-Makro hinzugefügt %f, das Mikrosekunden ausführt . Ich bin mir nicht sicher, ob dies irgendwo dokumentiert ist. Wenn Sie jedoch 2.6 oder 3.0 verwenden, können Sie dies tun:

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

Bearbeiten: Ich arbeite nie wirklich mit dem timeModul, daher habe ich dies zunächst nicht bemerkt, aber es scheint, dass time.struct_time keine Millisekunden / Mikrosekunden speichert. Sie sind möglicherweise besser dran datetime, wenn Sie Folgendes verwenden :

>>> from datetime import datetime
>>> a = datetime.strptime('30/03/09 16:31:32.123', '%d/%m/%y %H:%M:%S.%f')
>>> a.microsecond
123000
DNS
quelle
4
Dank docs.python.org/library/datetime.html : Neu in Version 2.6: Zeit- und Datums- / Uhrzeitobjekte unterstützen einen% f-Formatcode, der auf die Anzahl der Mikrosekunden im Objekt erweitert wird und links auf sechs Stellen mit Nullen aufgefüllt wird.
Ilkinulas
5
Ich kann sagen, dass die Python-Dokumente aktualisiert werden müssen. Die Dokumente für das Zeitmodul sagen nichts darüber aus %f.
Phunehehe
14
Die Python-Dokumente ab Version 2.7.3 sind etwas irreführend. Für die Strptime kann% f tatsächlich eine beliebige Anzahl von Dezimalstellen darstellen, nicht nur 6, wie man es für Mikrosekunden erwarten könnte. Der obige Code würde also 32,123 Sekunden analysieren und als 123.000 µs speichern, was wir wollen.
Michael Scheper
9
Die Zahl in %fwird rechts (nicht links!) Mit Nullen auf 6 Dezimalstellen aufgefüllt . 1 wird auf 100000 analysiert, 12 wird auf 120000 analysiert und 1234567 produziertValueError: unconverted data remains: 7
user443854
17
Ist es nur ich oder war die Frage nach Millisekunden, nicht nach Mikrosekunden?
Purrell
12

Ich weiß, dass dies eine ältere Frage ist, aber ich verwende immer noch Python 2.4.3 und musste einen besseren Weg finden, um die Datenzeichenfolge in eine Datums- / Uhrzeitangabe zu konvertieren.

Die Lösung, wenn datetime% f nicht unterstützt und keinen Versuch / Ausnahme benötigt, lautet:

    (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 

Dies funktioniert für die Eingabezeichenfolge "2010-10-06 09: 42: 52.266000".

Andrew Stern
quelle
1
dt.replace(microsecond=int(mSecs))
Haridsv
Dies gilt für Python 2.5 und früher. Python 2.6 unterstützt die Strptime '% f'
smci
4

Um den Code anzugeben, auf den sich die Antwort von nstehr bezieht (aus seiner Quelle ):

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
Phil H.
quelle
2

Die obige DNS-Antwort ist tatsächlich falsch. Die SO fragt nach Millisekunden, aber die Antwort ist für Mikrosekunden. Leider hat Python`s keine Direktive für Millisekunden, nur Mikrosekunden (siehe Dokument ), aber Sie können dies umgehen, indem Sie drei Nullen am Ende der Zeichenfolge anhängen und die Zeichenfolge als Mikrosekunden analysieren.

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

wo time_strist formatiert wie 30/03/09 16:31:32.123.

Hoffe das hilft.

Rafid
quelle
2
Anfangs dachte ich das Gleiche, aber siehe die Kommentare zur Antwort und die Dokumente . Es ist links-null-aufgefüllte Mikrosekunden, wird also .123korrekt als 123.000 Mikrosekunden interpretiert
aschmied
1

Mein erster Gedanke war, es '30 / 03/09 16: 31: 32.123 'zu übergeben (mit einem Punkt anstelle eines Doppelpunkts zwischen den Sekunden und den Millisekunden). Aber das hat nicht funktioniert. Ein kurzer Blick auf die Dokumente zeigt, dass Sekundenbruchteile auf jeden Fall ignoriert werden ...

Ah, Versionsunterschiede. Dies wurde als Fehler gemeldet und jetzt in Version 2.6+ können Sie "% S.% f" verwenden, um es zu analysieren.

MarkusQ
quelle
Das funktioniert nicht; time.strptime macht einfach keine Millisekunden.
DNS
1

aus Python-Mailinglisten: Analysieren des Millisekunden-Threads . Dort gibt es eine Funktion, die den Job zu erledigen scheint, obwohl es, wie in den Kommentaren des Autors erwähnt, eine Art Hack ist. Es verwendet reguläre Ausdrücke, um die Ausnahme zu behandeln, die ausgelöst wird, und führt dann einige Berechnungen durch.

Sie können auch versuchen, die regulären Ausdrücke und Berechnungen im Voraus durchzuführen, bevor Sie sie an strptime übergeben.

nstehr
quelle
Ja, ich kenne diesen Thread. Aber ich suche einen einfacheren Weg. Gibt es ein Modul in der Standard-Python-Bibliothek, mit dem die Zeit in Millisekunden analysiert werden kann?
Ilkinulas
1

Für Python 2 habe ich das gemacht

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

Es gibt die Zeit "% H:% M:% S" aus, teilt die time.time () in zwei Teilzeichenfolgen (vor und nach der.) xxxxxxx.xx auf und da .xx meine Millisekunden sind, füge ich die zweite Teilzeichenfolge zu meiner "%" hinzu. H:% M:% S

hoffe das macht Sinn :) Beispielausgabe:

13: 31: 21.72 Blink 01


13: 31: 21.81 ENDE DES BLINKS 01


13: 31: 26.3 Blink 01


13: 31: 26.39 ENDE DES BLINKS 01


13: 31: 34.65 Startspur 01


Papatrexas
quelle