Come calcolare l'intervallo di tempo tra due stringhe di tempo


169

Ho due volte, un orario di inizio e uno di fine, nel formato 10:33:26 (HH: MM: SS). Ho bisogno della differenza tra le due volte. Ho cercato la documentazione per Python e ho cercato online e immagino che avrebbe qualcosa a che fare con i moduli datetime e / o time. Non riesco a farlo funzionare correttamente e continuo a trovare solo come farlo quando è coinvolta una data.

In definitiva, devo calcolare le medie di più durate temporali. Ho le differenze di tempo per funzionare e le sto memorizzando in un elenco. Ora devo calcolare la media. Sto usando espressioni regolari per analizzare i tempi originali e quindi fare le differenze.

Per la media, devo convertire in secondi e poi in media?


2
Puoi pubblicare il tuo codice che hai provato e possiamo iniziare da lì?
Anthony Forloney,

Risposte:


201

Sì, sicuramente datetimeè quello che ti serve qui. In particolare, la strptimefunzione, che analizza una stringa in un oggetto tempo.

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)

Questo ti dà un timedeltaoggetto che contiene la differenza tra le due volte. Puoi fare quello che vuoi, ad esempio convertendolo in secondi o aggiungendolo a un altro datetime.

Ciò restituirà un risultato negativo se l'ora di fine è precedente all'ora di inizio, ad esempio s1 = 12:00:00e s2 = 05:00:00. Se si desidera che il codice presupponga che l'intervallo attraversi la mezzanotte in questo caso (ovvero che si supponga che l'ora di fine non sia mai precedente all'ora di inizio), è possibile aggiungere le seguenti righe al codice sopra:

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

(ovviamente è necessario includere from datetime import timedeltada qualche parte). Grazie a JF Sebastian per aver segnalato questo caso d'uso.


L'hack del tempo negativo non funzionerà quando days= -2e sopra nell'oggetto tdelta.
CKM

@chandresh Sì, ma daysnon può mai essere -2 o meno senza che vi siano ulteriori informazioni (in particolare date) oltre a quanto descritto nella domanda. Quindi questa situazione non è rilevante qui.
David Z,

3
Suggerimento: per ottenere il delta del tempo in secondi devi chiamare tdelta.total_seconds().
scai,

156

Prova questo: è efficiente per il cronometraggio di eventi a breve termine. Se qualcosa richiede più di un'ora, probabilmente il display finale vorrà una formattazione intuitiva.

import time
start = time.time()

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

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

La differenza di tempo viene restituita come il numero di secondi trascorsi.


5
Perché questa non è stata la risposta accettata? È semplice, dà un valore che può essere paragonato a qualcosa (l'esecuzione del mio comando ha richiesto più di 2,5 secondi?) E funziona in v2.7
Mawg dice di ripristinare Monica il

11
@Mawg Perché non risponde alla domanda dei PO. Stava chiedendo come confrontare due diverse volte che già ha in un determinato formato, non come generarle temporizzando un evento nel suo codice. Sono problemi piuttosto diversi.
Natsukane,

2
Non dovresti usare questo; usa invece il tempo monotonico ( time.monotonic()in Python). time.time()può tornare indietro (ad esempio, quando l'ora sulla macchina cambia, comprese le correzioni NTP).
nemequ

1
Non
pertinente

14

Ecco una soluzione che supporta la ricerca della differenza anche se l'ora di fine è inferiore all'ora di inizio (a intervalli di mezzanotte) come 23:55:00-00:25:00(durata di mezz'ora):

#!/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())

Produzione

0:42:23
0:30:00

time_diff()restituisce un oggetto timedelta che è possibile passare (come parte della sequenza) mean()direttamente a una funzione, ad esempio:

#!/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

Il mean()risultato è anche un timedelta()oggetto che puoi convertire in secondi ( td.total_seconds()metodo (da Python 2.7)), ore ( td / timedelta(hours=1)(Python 3)), ecc.


@JF Mi chiedo se la statistica significhi e le funzioni di varianza funzionino direttamente con l'oggetto timedelta ora? Qualche pensiero su questo? Inoltre, qualsiasi aiuto per calcolare la varianza degli oggetti timedelta sarà utile.
CKM

@chandresh: non è supportato. È possibile convertire in secondi / microsecondi per il calcolo delle statistiche matematiche dei timedeltas.
jfs,

11

La struttura che rappresenta la differenza di tempo in Python si chiama timedelta . Se hai start_timee end_timecome datetimetipi puoi calcolare la differenza usando un -operatore come:

diff = end_time - start_time

dovresti farlo prima di convertirlo in un formato stringa particolare (ad es. prima di start_time.strftime (...)). Nel caso in cui tu abbia già una rappresentazione in forma di stringa, devi convertirla in time / datetime usando il metodo strptime .


10

Questo sito dice di provare:

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 

Questo forum utilizza time.mktime ()


Assicurarsi che se si utilizza% p (AM / PM) che si utilizza% I (12 ore) anziché% H (24 ore): docs.python.org/2/library/…
Andrew,

6

Mi piace come lo fa questo ragazzo - https://amalgjose.com/2015/02/19/python-code-for-calculating-the-difference-b Between - two - time - stamps . Non sono sicuro se ha alcuni svantaggi.

Ma sembra pulito per me :)

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)

Per quanto riguarda la domanda che devi ancora usare datetime.strptime()come altri hanno già detto prima.


3

Prova questo

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

PRODUZIONE :

0:00:05

Il nucleo di questa risposta non differisce affatto dalla risposta accettata di sei anni e altamente votata. Hai davvero qualcosa da aggiungere? Non ha senso inviare una risposta completamente ridondante.
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,
)

risultato: 0 0 0 0 -47 -37


1

Entrambi timee datetimehanno un componente data.

Normalmente se hai solo a che fare con la parte temporale forniresti una data predefinita. Se sei solo interessato alla differenza e sai che entrambe le volte sono nello stesso giorno, costruisci una datetimeper ognuna con il giorno impostato su oggi e sottrai l'inizio dall'ora di fine per ottenere l'intervallo ( timedelta).


1

Dai un'occhiata al modulo datetime e agli oggetti timedelta. Dovresti finire per costruire un oggetto datetime per i tempi di inizio e fine e, quando li sottraggerai, otterrai un timedelta.


0

Conciso se sei solo interessato al tempo trascorso che è inferiore a 24 ore. È possibile formattare l'output secondo necessità nell'istruzione return:

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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.