So berechnen Sie das Zeitintervall zwischen zwei Zeitzeichenfolgen

169

Ich habe zwei Mal eine Start- und eine Stoppzeit im Format 10:33:26 (HH: MM: SS). Ich brauche den Unterschied zwischen den beiden Zeiten. Ich habe die Dokumentation nach Python durchgesehen und online gesucht, und ich würde mir vorstellen, dass dies etwas mit den Datums- und / oder Zeitmodulen zu tun hat. Ich kann es nicht richtig zum Laufen bringen und finde immer wieder heraus, wie das geht, wenn es um ein Datum geht.

Letztendlich muss ich die Durchschnittswerte mehrerer Zeitdauern berechnen. Ich habe die Zeitunterschiede zum Arbeiten und speichere sie in einer Liste. Ich muss jetzt den Durchschnitt berechnen. Ich verwende reguläre Ausdrücke, um die ursprünglichen Zeiten zu analysieren und dann die Unterschiede zu machen.

Soll ich für die Mittelwertbildung in Sekunden konvertieren und dann mitteln?

Hannah
quelle
2
Können Sie Ihren Code posten, den Sie ausprobiert haben, und wir können von dort aus beginnen?
Anthony Forloney

Antworten:

200

Ja, definitiv datetimeist das, was Sie hier brauchen. Insbesondere die strptimeFunktion, die eine Zeichenfolge in ein Zeitobjekt analysiert.

from datetime import datetime
s1 = '10:33:26'
s2 = '11:15:49' # for example
FMT = '%H:%M:%S'
tdelta = datetime.strptime(s2, FMT) - datetime.strptime(s1, FMT)

Dadurch erhalten Sie ein timedeltaObjekt, das den Unterschied zwischen den beiden Zeiten enthält. Damit können Sie tun, was Sie wollen, z. B. in Sekunden konvertieren oder zu einem anderen hinzufügen datetime.

Dies gibt ein negatives Ergebnis zurück, wenn die Endzeit früher als die Startzeit ist, z. B. s1 = 12:00:00und s2 = 05:00:00. Wenn der Code in diesem Fall davon ausgehen soll, dass das Intervall Mitternacht überschreitet (dh angenommen wird, dass die Endzeit niemals vor der Startzeit liegt), können Sie dem obigen Code die folgenden Zeilen hinzufügen:

if tdelta.days < 0:
    tdelta = timedelta(days=0,
                seconds=tdelta.seconds, microseconds=tdelta.microseconds)

(Natürlich müssen Sie from datetime import timedeltairgendwo einschließen ). Vielen Dank an JF Sebastian für den Hinweis auf diesen Anwendungsfall.

David Z.
quelle
Ein negativer Zeit-Hack funktioniert nicht, wenn days= -2und darüber im tdelta-Objekt.
CKM
@chandresh Ja, dayskann aber niemals -2 oder weniger sein, ohne dass zusätzliche Informationen (insbesondere Daten) vorliegen, die über die in der Frage beschriebenen hinausgehen. Diese Situation ist hier also nicht relevant.
David Z
3
Tipp: Um das Zeitdelta in Sekunden zu erhalten, müssen Sie anrufen tdelta.total_seconds().
Scai
156

Versuchen Sie dies - es ist effizient, um kurzfristige Ereignisse zu planen. Wenn etwas länger als eine Stunde dauert, wird die endgültige Anzeige wahrscheinlich eine freundliche Formatierung erfordern.

import time
start = time.time()

time.sleep(10)  # or do something more productive

done = time.time()
elapsed = done - start
print(elapsed)

Die Zeitdifferenz wird als Anzahl der verstrichenen Sekunden zurückgegeben.

Bill Grava
quelle
5
Warum war das nicht die akzeptierte Antwort? Es ist einfach, es gibt einen Wert, der mit etwas verglichen werden kann (hat die Ausführung meines Befehls mehr als 2,5 Sekunden gedauert?) Und es funktioniert in Version 2.7
Mawg sagt, Monica
11
@Mawg Weil es die OP-Frage nicht beantwortet. Er fragte, wie man zwei verschiedene Zeiten vergleicht, die er bereits in einem bestimmten Format hat, und nicht, wie man sie generiert, indem man ein Ereignis in seinem Code zeitlich festlegt. Das sind ziemlich unterschiedliche Probleme.
Natsukane
2
Sie sollten dies nicht verwenden; Verwenden Sie stattdessen die monotone Zeit ( time.monotonic()in Python). time.time()kann rückwärts gehen (z. B. wenn sich die Zeit auf dem Computer ändert, einschließlich NTP-Korrekturen).
Nemequ
1
Irrelevant zu hinterfragen
patricktokeeffe
14

Hier ist eine Lösung, die das Ermitteln des Unterschieds unterstützt, selbst wenn die Endzeit kürzer als die Startzeit (über Mitternachtsintervall) ist, z. B. 23:55:00-00:25:00(eine halbe Stunde Dauer):

#!/usr/bin/env python
from datetime import datetime, time as datetime_time, timedelta

def time_diff(start, end):
    if isinstance(start, datetime_time): # convert to datetime
        assert isinstance(end, datetime_time)
        start, end = [datetime.combine(datetime.min, t) for t in [start, end]]
    if start <= end: # e.g., 10:33:26-11:15:49
        return end - start
    else: # end < start e.g., 23:55:00-00:25:00
        end += timedelta(1) # +day
        assert end > start
        return end - start

for time_range in ['10:33:26-11:15:49', '23:55:00-00:25:00']:
    s, e = [datetime.strptime(t, '%H:%M:%S') for t in time_range.split('-')]
    print(time_diff(s, e))
    assert time_diff(s, e) == time_diff(s.time(), e.time())

Ausgabe

0:42:23
0:30:00

time_diff()Gibt ein Timedelta-Objekt zurück, das Sie (als Teil der Sequenz) mean()direkt an eine Funktion übergeben können, z.

#!/usr/bin/env python
from datetime import timedelta

def mean(data, start=timedelta(0)):
    """Find arithmetic average."""
    return sum(data, start) / len(data)

data = [timedelta(minutes=42, seconds=23), # 0:42:23
        timedelta(minutes=30)] # 0:30:00
print(repr(mean(data)))
# -> datetime.timedelta(0, 2171, 500000) # days, seconds, microseconds

Das mean()Ergebnis ist auch ein timedelta()Objekt, das Sie in Sekunden ( td.total_seconds()Methode (seit Python 2.7)), Stunden ( td / timedelta(hours=1)(Python 3)) usw. konvertieren können .

jfs
quelle
@JF Ich frage mich, ob Statistikmittel- und Varianzfunktionen jetzt direkt mit dem Timedelta-Objekt funktionieren. Irgendwelche Gedanken dazu? Außerdem ist jede Hilfe zur Berechnung der Varianz von Timedelta-Objekten hilfreich.
CKM
@chandresh: Es wird nicht unterstützt. Sie können zur Berechnung der mathematischen Statistik von Zeitdeltas in Sekunden / Mikrosekunden konvertieren.
JFS
11

Eine Struktur, die den Zeitunterschied in Python darstellt, wird als Zeitdelta bezeichnet . Wenn Sie start_timeund end_timeals datetimeTypen haben, können Sie die Differenz mit folgenden -Operatoren berechnen :

diff = end_time - start_time

Sie sollten dies tun, bevor Sie in ein bestimmtes Zeichenfolgenformat konvertieren (z. B. vor start_time.strftime (...)). Falls Sie bereits eine Zeichenfolgendarstellung haben, müssen Sie diese mithilfe der strptime- Methode zurück in time / datetime konvertieren .

dzida
quelle
10

Diese Seite sagt zu versuchen:

import datetime as dt
start="09:35:23"
end="10:23:00"
start_dt = dt.datetime.strptime(start, '%H:%M:%S')
end_dt = dt.datetime.strptime(end, '%H:%M:%S')
diff = (end_dt - start_dt) 
diff.seconds/60 

Dieses Forum verwendet time.mktime ()

Kyra
quelle
Stellen Sie sicher, dass Sie bei Verwendung von% p (AM / PM)% I (12 Stunden) anstelle von% H (24 Stunden) verwenden: docs.python.org/2/library/…
Andrew
6

Mir gefällt, wie dieser Typ das macht - https://amalgjose.com/2015/02/19/python-code-for-calculating-the-difference-between-two-time-stamps . Ich bin mir nicht sicher, ob es Nachteile hat.

Sieht aber ordentlich aus für mich :)

from datetime import datetime
from dateutil.relativedelta import relativedelta

t_a = datetime.now()
t_b = datetime.now()

def diff(t_a, t_b):
    t_diff = relativedelta(t_b, t_a)  # later/end time comes first!
    return '{h}h {m}m {s}s'.format(h=t_diff.hours, m=t_diff.minutes, s=t_diff.seconds)

In Bezug auf die Frage müssen Sie noch verwenden, datetime.strptime()wie andere zuvor gesagt haben.

antonavy
quelle
3

Versuche dies

import datetime
import time
start_time = datetime.datetime.now().time().strftime('%H:%M:%S')
time.sleep(5)
end_time = datetime.datetime.now().time().strftime('%H:%M:%S')
total_time=(datetime.datetime.strptime(end_time,'%H:%M:%S') - datetime.datetime.strptime(start_time,'%H:%M:%S'))
print total_time

AUSGABE :

0:00:05
Dipnesh Parakhiya
quelle
Der Kern dieser Antwort unterscheidet sich überhaupt nicht von der sechs Jahre alten und hoch bewerteten akzeptierten Antwort. Haben Sie tatsächlich etwas hinzuzufügen? Es macht keinen Sinn, eine völlig redundante Antwort einzureichen.
Blckknght
2
import datetime as dt
from dateutil.relativedelta import relativedelta

start = "09:35:23"
end = "10:23:00"
start_dt = dt.datetime.strptime(start, "%H:%M:%S")
end_dt = dt.datetime.strptime(end, "%H:%M:%S")
timedelta_obj = relativedelta(start_dt, end_dt)
print(
    timedelta_obj.years,
    timedelta_obj.months,
    timedelta_obj.days,
    timedelta_obj.hours,
    timedelta_obj.minutes,
    timedelta_obj.seconds,
)

Ergebnis: 0 0 0 0 -47 -37

hu goao
quelle
1

Beide timeund datetimehaben eine Datumskomponente.

Wenn Sie sich nur mit dem Zeitteil befassen, geben Sie normalerweise ein Standarddatum an. Wenn Sie nur an dem Unterschied interessiert sind und wissen, dass beide Zeiten am selben Tag liegen, konstruieren Sie datetimefür jeden einen Tag mit dem heutigen Tag und subtrahieren Sie den Start von der Stoppzeit, um das Intervall ( timedelta) zu erhalten.

ChrisF
quelle
1

Schauen Sie sich das datetime-Modul und die timedelta-Objekte an. Am Ende sollten Sie ein Datum / Uhrzeit-Objekt für die Start- und Stoppzeiten erstellen. Wenn Sie diese subtrahieren, erhalten Sie ein Zeitdelta.

Pierce
quelle
0

Kurz gesagt, wenn Sie nur an der verstrichenen Zeit interessiert sind, die unter 24 Stunden liegt. Sie können die Ausgabe nach Bedarf in der return-Anweisung formatieren:

import datetime
def elapsed_interval(start,end):
    elapsed = end - start
    min,secs=divmod(elapsed.days * 86400 + elapsed.seconds, 60)
    hour, minutes = divmod(min, 60)
    return '%.2d:%.2d:%.2d' % (hour,minutes,secs)

if __name__ == '__main__':
    time_start=datetime.datetime.now()
    """ do your process """
    time_end=datetime.datetime.now()
    total_time=elapsed_interval(time_start,time_end)
user2654744
quelle