Risposte:
>>> import datetime
>>> first_time = datetime.datetime.now()
>>> later_time = datetime.datetime.now()
>>> difference = later_time - first_time
>>> seconds_in_day = 24 * 60 * 60
datetime.timedelta(0, 8, 562000)
>>> divmod(difference.days * seconds_in_day + difference.seconds, 60)
(0, 8) # 0 minutes, 8 seconds
Sottraendo la volta successiva dalla prima volta si difference = later_time - first_time
crea un oggetto datetime che contiene solo la differenza. Nell'esempio sopra sono 0 minuti, 8 secondi e 562000 microsecondi.
delorean
travisamenti datetime
, pytz
approccio ad esempio, l'esempio di codice iniziale potrebbe essere scritto come d = datetime.now(timezone(EST))
(una riga leggibile anziché cinque).
Una novità di Python 2.7 è il timedelta
metodo di istanza .total_seconds()
. Dai documenti di Python, questo equivale a (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6
.
Riferimento: http://docs.python.org/2/library/datetime.html#datetime.timedelta.total_seconds
>>> import datetime
>>> time1 = datetime.datetime.now()
>>> time2 = datetime.datetime.now() # waited a few minutes before pressing enter
>>> elapsedTime = time2 - time1
>>> elapsedTime
datetime.timedelta(0, 125, 749430)
>>> divmod(elapsedTime.total_seconds(), 60)
(2.0, 5.749430000000004) # divmod returns quotient and remainder
# 2 minutes, 5.74943 seconds
Utilizzando l'esempio datetime
>>> from datetime import datetime
>>> then = datetime(2012, 3, 5, 23, 8, 15) # Random date in the past
>>> now = datetime.now() # Now
>>> duration = now - then # For build-in functions
>>> duration_in_s = duration.total_seconds() # Total number of seconds between dates
Durata in anni
>>> years = divmod(duration_in_s, 31536000)[0] # Seconds in a year=365*24*60*60 = 31536000.
Durata in giorni
>>> days = duration.days # Build-in datetime function
>>> days = divmod(duration_in_s, 86400)[0] # Seconds in a day = 86400
Durata in ore
>>> hours = divmod(duration_in_s, 3600)[0] # Seconds in an hour = 3600
Durata in minuti
>>> minutes = divmod(duration_in_s, 60)[0] # Seconds in a minute = 60
Durata in secondi
>>> seconds = duration.seconds # Build-in datetime function
>>> seconds = duration_in_s
Durata in microsecondi
>>> microseconds = duration.microseconds # Build-in datetime function
Durata totale tra le due date
>>> days = divmod(duration_in_s, 86400) # Get days (without [0]!)
>>> hours = divmod(days[1], 3600) # Use remainder of days to calc hours
>>> minutes = divmod(hours[1], 60) # Use remainder of hours to calc minutes
>>> seconds = divmod(minutes[1], 1) # Use remainder of minutes to calc seconds
>>> print("Time between dates: %d days, %d hours, %d minutes and %d seconds" % (days[0], hours[0], minutes[0], seconds[0]))
o semplicemente:
>>> print(now - then)
Modifica 2019 Dato che questa risposta ha guadagnato trazione, aggiungerò una funzione, che potrebbe semplificarne l'utilizzo per alcuni
from datetime import datetime
def getDuration(then, now = datetime.now(), interval = "default"):
# Returns a duration as specified by variable interval
# Functions, except totalDuration, returns [quotient, remainder]
duration = now - then # For build-in functions
duration_in_s = duration.total_seconds()
def years():
return divmod(duration_in_s, 31536000) # Seconds in a year=31536000.
def days(seconds = None):
return divmod(seconds if seconds != None else duration_in_s, 86400) # Seconds in a day = 86400
def hours(seconds = None):
return divmod(seconds if seconds != None else duration_in_s, 3600) # Seconds in an hour = 3600
def minutes(seconds = None):
return divmod(seconds if seconds != None else duration_in_s, 60) # Seconds in a minute = 60
def seconds(seconds = None):
if seconds != None:
return divmod(seconds, 1)
return duration_in_s
def totalDuration():
y = years()
d = days(y[1]) # Use remainder to calculate next variable
h = hours(d[1])
m = minutes(h[1])
s = seconds(m[1])
return "Time between dates: {} years, {} days, {} hours, {} minutes and {} seconds".format(int(y[0]), int(d[0]), int(h[0]), int(m[0]), int(s[0]))
return {
'years': int(years()[0]),
'days': int(days()[0]),
'hours': int(hours()[0]),
'minutes': int(minutes()[0]),
'seconds': int(seconds()),
'default': totalDuration()
}[interval]
# Example usage
then = datetime(2012, 3, 5, 23, 8, 15)
now = datetime.now()
print(getDuration(then)) # E.g. Time between dates: 7 years, 208 days, 21 hours, 19 minutes and 15 seconds
print(getDuration(then, now, 'years')) # Prints duration in years
print(getDuration(then, now, 'days')) # days
print(getDuration(then, now, 'hours')) # hours
print(getDuration(then, now, 'minutes')) # minutes
print(getDuration(then, now, 'seconds')) # seconds
TypeError: 'float' object is not subscriptable
quando uso per:then = datetime(2017, 8, 11, 15, 58, tzinfo=pytz.UTC)
now = datetime(2018, 8, 11, 15, 58, tzinfo=pytz.UTC)
getDuration(then, now, 'years')
Sottrarre l'uno dall'altro. Ottieni un timedelta
oggetto con la differenza.
>>> import datetime
>>> d1 = datetime.datetime.now()
>>> d2 = datetime.datetime.now() # after a 5-second or so pause
>>> d2 - d1
datetime.timedelta(0, 5, 203000)
È possibile convertire dd.days
, dd.seconds
ed dd.microseconds
a pochi minuti.
Se a
, b
sono oggetti datetime, allora per trovare la differenza di tempo tra loro in Python 3:
from datetime import timedelta
time_difference = a - b
time_difference_in_minutes = time_difference / timedelta(minutes=1)
Nelle versioni precedenti di Python:
time_difference_in_minutes = time_difference.total_seconds() / 60
Se a
, b
sono oggetti datetime naive come quella restituita dalla datetime.now()
allora il risultato può essere sbagliato se gli oggetti rappresentano ora locale con diverse UTC offset ad esempio, le transizioni in tutto o DST per le date / future passate. Maggiori dettagli: Scopri se sono trascorse 24 ore tra un periodo di tempo e l'altro - Python .
Per ottenere risultati affidabili, utilizzare l'ora UTC o gli oggetti datetime sensibili al fuso orario.
Usa divmod:
now = int(time.time()) # epoch seconds
then = now - 90000 # some time in the past
d = divmod(now-then,86400) # days
h = divmod(d[1],3600) # hours
m = divmod(h[1],60) # minutes
s = m[1] # seconds
print '%d days, %d hours, %d minutes, %d seconds' % (d[0],h[0],m[0],s)
Ecco come ottengo il numero di ore trascorse tra due oggetti datetime.datetime:
before = datetime.datetime.now()
after = datetime.datetime.now()
hours = math.floor(((after - before).seconds) / 3600)
timedelta.seconds
fornisce solo il numero di secondi memorizzati in modo esplicito , che la garanzia della documentazione avrà in totale meno di un giorno. Volete (after - before).total_seconds()
, che fornisce il numero di secondi che coprono l' intero delta.
(after - before).total_seconds() // 3600
(Python 2.7) o (after - before) // timedelta(seconds=3600)
(Python 3)
Per trovare solo il numero di giorni: timedelta ha un attributo 'giorni'. Puoi semplicemente interrogarlo.
>>>from datetime import datetime, timedelta
>>>d1 = datetime(2015, 9, 12, 13, 9, 45)
>>>d2 = datetime(2015, 8, 29, 21, 10, 12)
>>>d3 = d1- d2
>>>print d3
13 days, 15:59:33
>>>print d3.days
13
Ho pensato che potesse essere utile menzionare anche la formattazione per quanto riguarda timedelta. strptime () analizza una stringa che rappresenta un'ora in base a un formato.
from datetime import datetime
datetimeFormat = '%Y/%m/%d %H:%M:%S.%f'
time1 = '2016/03/16 10:01:28.585'
time2 = '2016/03/16 09:56:28.067'
time_dif = datetime.strptime(time1, datetimeFormat) - datetime.strptime(time2,datetimeFormat)
print(time_dif)
Questo produrrà: 0: 05: 00.518000
Uso qualcosa del genere:
from datetime import datetime
def check_time_difference(t1: datetime, t2: datetime):
t1_date = datetime(
t1.year,
t1.month,
t1.day,
t1.hour,
t1.minute,
t1.second)
t2_date = datetime(
t2.year,
t2.month,
t2.day,
t2.hour,
t2.minute,
t2.second)
t_elapsed = t1_date - t2_date
return t_elapsed
# usage
f = "%Y-%m-%d %H:%M:%S+01:00"
t1 = datetime.strptime("2018-03-07 22:56:57+01:00", f)
t2 = datetime.strptime("2018-03-07 22:48:05+01:00", f)
elapsed_time = check_time_difference(t1, t2)
print(elapsed_time)
#return : 0:08:52
return t1-t2
Questo è il mio approccio usando mktime .
from datetime import datetime, timedelta
from time import mktime
yesterday = datetime.now() - timedelta(days=1)
today = datetime.now()
difference_in_seconds = abs(mktime(yesterday.timetuple()) - mktime(today.timetuple()))
difference_in_minutes = difference_in_seconds / 60
mktime()
si aspetta l'ora locale come input. L'ora locale mktime()
potrebbe essere ambigua e potrebbe restituire una risposta errata in questo caso. Utilizzare a - b
invece (a, b - oggetti datetime) . mktime()
non è necessario e talvolta è sbagliato. Non usarlo in questo caso.
In altri modi per ottenere la differenza tra la data;
import dateutil.parser
import datetime
last_sent_date = "" # date string
timeDifference = current_date - dateutil.parser.parse(last_sent_date)
time_difference_in_minutes = (int(timeDifference.days) * 24 * 60) + int((timeDifference.seconds) / 60)
Quindi ottieni output in Min.
Grazie
Ho usato le differenze di tempo per i test di integrazione continua per verificare e migliorare le mie funzioni. Ecco un semplice codice se qualcuno ne ha bisogno
from datetime import datetime
class TimeLogger:
time_cursor = None
def pin_time(self):
global time_cursor
time_cursor = datetime.now()
def log(self, text=None) -> float:
global time_cursor
if not time_cursor:
time_cursor = datetime.now()
now = datetime.now()
t_delta = now - time_cursor
seconds = t_delta.total_seconds()
result = str(now) + ' tl -----------> %.5f' % seconds
if text:
result += " " + text
print(result)
self.pin_time()
return seconds
time_logger = TimeLogger()
usando:
from .tests_time_logger import time_logger
class Tests(TestCase):
def test_workflow(self):
time_logger.pin_time()
... my functions here ...
time_logger.log()
... other function(s) ...
time_logger.log(text='Tests finished')
e ho qualcosa del genere nell'output del registro
2019-12-20 17:19:23.635297 tl -----------> 0.00007
2019-12-20 17:19:28.147656 tl -----------> 4.51234 Tests finished
Sulla base della grande risposta di @Attaque , propongo una versione semplificata più breve del calcolatore della differenza di data e ora:
seconds_mapping = {
'y': 31536000,
'm': 2628002.88, # this is approximate, 365 / 12; use with caution
'w': 604800,
'd': 86400,
'h': 3600,
'min': 60,
's': 1,
'mil': 0.001,
}
def get_duration(d1, d2, interval, with_reminder=False):
if with_reminder:
return divmod((d2 - d1).total_seconds(), seconds_mapping[interval])
else:
return (d2 - d1).total_seconds() / seconds_mapping[interval]
L'ho modificato per evitare di dichiarare funzioni ripetitive, rimosso l'intervallo predefinito di stampa piuttosto e aggiunto il supporto per millisecondi, settimane e mesi ISO (i mesi nudi sono solo approssimativi, in base al presupposto che ogni mese è uguale a 365/12
).
Che produce:
d1 = datetime(2011, 3, 1, 1, 1, 1, 1000)
d2 = datetime(2011, 4, 1, 1, 1, 1, 2500)
print(get_duration(d1, d2, 'y', True)) # => (0.0, 2678400.0015)
print(get_duration(d1, d2, 'm', True)) # => (1.0, 50397.12149999989)
print(get_duration(d1, d2, 'w', True)) # => (4.0, 259200.00149999978)
print(get_duration(d1, d2, 'd', True)) # => (31.0, 0.0014999997802078724)
print(get_duration(d1, d2, 'h', True)) # => (744.0, 0.0014999997802078724)
print(get_duration(d1, d2, 'min', True)) # => (44640.0, 0.0014999997802078724)
print(get_duration(d1, d2, 's', True)) # => (2678400.0, 0.0014999997802078724)
print(get_duration(d1, d2, 'mil', True)) # => (2678400001.0, 0.0004999997244524721)
print(get_duration(d1, d2, 'y', False)) # => 0.08493150689687975
print(get_duration(d1, d2, 'm', False)) # => 1.019176965856293
print(get_duration(d1, d2, 'w', False)) # => 4.428571431051587
print(get_duration(d1, d2, 'd', False)) # => 31.00000001736111
print(get_duration(d1, d2, 'h', False)) # => 744.0000004166666
print(get_duration(d1, d2, 'min', False)) # => 44640.000024999994
print(get_duration(d1, d2, 's', False)) # => 2678400.0015
print(get_duration(d1, d2, 'mil', False)) # => 2678400001.4999995