¿Cómo encuentro la diferencia horaria entre dos objetos de fecha y hora en Python?

Resuelto Hobhouse asked hace 15 años • 21 respuestas

¿ Cómo puedo saber la diferencia horaria en minutos entre dos datetimeobjetos?

Hobhouse avatar Aug 28 '09 16:08 Hobhouse
Aceptado
>>> import datetime
>>> first_time = datetime.datetime.now()
>>> later_time = datetime.datetime.now()
>>> difference = later_time - first_time
datetime.timedelta(0, 8, 562000)
>>> seconds_in_day = 24 * 60 * 60
>>> divmod(difference.days * seconds_in_day + difference.seconds, 60)
(0, 8)      # 0 minutes, 8 seconds

Restar la hora posterior de la primera difference = later_time - first_timecrea un objeto de fecha y hora que solo contiene la diferencia. En el ejemplo anterior son 0 minutos, 8 segundos y 562000 microsegundos.

SilentGhost avatar Aug 28 '2009 09:08 SilentGhost

Usando el ejemplo de fecha y hora

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

Duración en años

>>> years = divmod(duration_in_s, 31536000)[0]    # Seconds in a year=365*24*60*60 = 31536000.

Duración en días

>>> days  = duration.days                         # Build-in datetime function
>>> days  = divmod(duration_in_s, 86400)[0]       # Seconds in a day = 86400

Duración en horas

>>> hours = divmod(duration_in_s, 3600)[0]        # Seconds in an hour = 3600

Duración en minutos

>>> minutes = divmod(duration_in_s, 60)[0]        # Seconds in a minute = 60

Duración en segundos

[!] Vea la advertencia sobre el uso de la duración en segundos al final de esta publicación.

>>> seconds = duration.seconds                    # Build-in datetime function
>>> seconds = duration_in_s

Duración en microsegundos

[!] Vea la advertencia sobre el uso de la duración en microsegundos al final de esta publicación.

>>> microseconds = duration.microseconds          # Build-in datetime function

Duración total entre las dos fechas

>>> 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 simplemente:

>>> print(now - then)

Editar 2019 Dado que esta respuesta ha ganado fuerza, agregaré una función que podría simplificar el uso para algunos

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

Advertencia: Advertencia sobre los .segundos y .microsegundos integrados
datetime.seconds y datetime.microsecondsestán limitados a [0,86400) y [0,10^6) respectivamente.

Deben usarse con cuidado si timedelta es mayor que el valor máximo devuelto.

Ejemplos:

endes 1h y 200μs después start:

>>> start = datetime(2020,12,31,22,0,0,500)
>>> end = datetime(2020,12,31,23,0,0,700)
>>> delta = end - start
>>> delta.microseconds
RESULT: 200
EXPECTED: 3600000200

endes 1d y 1h después start:

>>> start = datetime(2020,12,30,22,0,0)
>>> end = datetime(2020,12,31,23,0,0)
>>> delta = end - start
>>> delta.seconds
RESULT: 3600
EXPECTED: 90000
Nicolai Lissau avatar Nov 09 '2017 16:11 Nicolai Lissau

Lo nuevo en Python 2.7 es el timedeltamétodo de instancia .total_seconds(). Según los documentos de Python, esto es equivalente a (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6.

Referencia: http://docs.python.org/2/library/datetime.html#datetime.timedelta.total_segundos

>>> 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
Ryan Stanley avatar Sep 29 '2012 16:09 Ryan Stanley

Simplemente resta uno del otro. Obtienes un timedeltaobjeto con la diferencia.

>>> import datetime
>>> d1 = datetime.datetime.now()
>>> d2 = datetime.datetime.now() # after a 5-second or so pause
>>> d2 - d1
datetime.timedelta(0, 5, 203000)
>>> dd = d2 - d1
>>> print (dd.days) # get days
>>> print (dd.seconds) # get seconds
>>> print (dd.microseconds) # get microseconds
>>> print (int(round(dd.total_seconds()/60, 0))) # get minutes
Vinay Sajip avatar Aug 28 '2009 09:08 Vinay Sajip

Si son objetos de fecha y hora a, bentonces para encontrar la diferencia horaria entre ellos en Python 3:

from datetime import timedelta

time_difference = a - b
time_difference_in_minutes = time_difference / timedelta(minutes=1)

En versiones anteriores de Python:

time_difference_in_minutes = time_difference.total_seconds() / 60

Si son objetos de fecha y hora ingenuos, como los devueltos por, aentonces el resultado puede ser incorrecto si los objetos representan la hora local con diferentes compensaciones UTC, por ejemplo, alrededor de transiciones de horario de verano o para fechas pasadas/futuras. Más detalles: Encuentre si han pasado 24 horas entre fechas y horas - Python .bdatetime.now()

Para obtener resultados confiables, utilice la hora UTC o objetos de fecha y hora que tengan en cuenta la zona horaria.

jfs avatar Oct 27 '2014 11:10 jfs