Programa en Python para calcular el número de días entre dos fechas

El siguiente código es un programa en Python que calcula el número de días transcurridos entre dos fechas cualesquiera. Reconozco que me ha llevado mi tiempo programarlo y no ha sido fácil para un novato en Python como yo, lo que posiblemente lleve a que el código se pueda optimizar de muchas formas. En cualquier caso el programa funciona y es divertido ponerlo a prueba con algunas fechas. En general, la resolución del algoritmo tiene los siguientes matices:

  • Se crea una función, llamada diasHastaFecha que recibe como entradas 6 números: día, mes y año de inicio, y día, mes y año final.
  • El primer código dentro de la función es otra función llamada esBisiesto que nos dice si un año es bisiesto o no. Está sacado directamente de la definición del algoritmo de año bisiesto que indica que un año es bisiesto si dicho año es divisible entre 4, excepto aquellos divisibles entre 100 pero no entre 400.
  • El resto del código está dividido en dos partes: una si el cálculo es entre diferentes años y otra si es dentro de un mismo año.
  • Si el cálculo es entre diferentes años, primero calculamos los días que quedan desde la fecha de inicio hasta el 31 de diciembre de dicho año. Se tiene en cuenta que si el año es bisiesto febrero tiene 29 días. Luego se calculan los días de los años intermedios entre fechas: 365 días los años normales y 366 días los años bisiestos. Por último se calcula los días que hay desde el 1 de enero del año final hasta la fecha indicada.
  • La segunda posibilidad es que la diferencia de días solicitada sean dentro del mismo año. El caso más sencillo es que sea además un cálculo dentro del mismo mes. En ese caso simple es tan sólo la diferencia entre los dos argumentos de entrada “días”. Si son diferentes meses, pues se calculan los días hasta final del primer mes, los días de meses intermedios y se le suma por último el número de día objetivo del mes final, todo ello considerando, igual que en los anteriores casos, que febrero tiene 28 o 29 días dependiendo de si el año es bisiesto.
  • Por último, pero no por ello menos importante, no se consideran posibles los viajes en el tiempo. Es decir, la fecha inicial debe ser siempre menor que la final. Es fácil implementar en el código un aviso de error si este caso sucediera, pero por no liarlo más se ha supuesto que la entrada es introducida correctamente por el usuario siempre.

El código es el siguiente:

def diasHastaFecha(day1, month1, year1, day2, month2, year2):
    
    # Función para calcular si un año es bisiesto o no
    
    def esBisiesto(year):
        return year % 4 == 0 and year % 100 != 0 or year % 400 == 0
    
    # Caso de años diferentes
    
    if (year1<year2):
        
        # Días restante primer año
        
        if esBisiesto(year1) == False:
            diasMes = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
        else:
            diasMes = [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
     
        restoMes = diasMes[month1] - day1
    
        restoYear = 0
        i = month1 + 1
    
        while i <= 12:
            restoYear = restoYear + diasMes[i]
            i = i + 1
    
        primerYear = restoMes + restoYear
    
        # Suma de días de los años que hay en medio
    
        sumYear = year1 + 1
        totalDias = 0
    
        while (sumYear<year2):
            if esBisiesto(sumYear) == False:
                totalDias = totalDias + 365
                sumYear = sumYear + 1
            else:
                totalDias = totalDias + 366
                sumYear = sumYear + 1
    
        # Dias año actual
    
        if esBisiesto(year2) == False:
            diasMes = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
        else:
            diasMes = [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    
        llevaYear = 0
        lastYear = 0
        i = 1
    
        while i < month2:
            llevaYear = llevaYear + diasMes[i]
            i = i + 1
    
        lastYear = day2 + llevaYear
    
        return totalDias + primerYear + lastYear
    
    # Si estamos en el mismo año
    
    else:
        
        if esBisiesto(year1) == False:
            diasMes = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
        else:
            diasMes = [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    
        llevaYear = 0
        total = 0
        i = month1
        
        if i < month2:
            while i < month2:
                llevaYear = llevaYear + diasMes[i]
                i = i + 1
            total = day2 + llevaYear - 1
            return total 
        else:
            total = day2 - day1
            return total

Algunos cálculos de ejemplo:

    • Días entre el 9 de febrero de 1978 y el 6 de marzo de 2019: 15.000 días (¡qué edad más buena!)
    • Días entre el 31 de diciembre de 1986 y el 1 de enero de 1987: 1 día. Sólo como test.
    • Días entre el 1 de febrero de 1996 y el 1 de marzo de 1996: 29 días, ya que 1996 fue un año bisiesto.
    • Días que llevaba muerto Napoleón Bonaparte a 21 de junio de 2018: ¡72.000 días! (que son algo más de 197 años).
    • Días entre los estrenos de Star Wars: Episodio IV y Star Wars: Episodio V – El Imperio contraataca en EEUU: 1.122 días.
    • Días desde que Cristóbal Colón descubrió américa a fecha 26 de junio de 2018: ¡192.000 días! Pero ojo porque esta tiene trampa. En 1492 el calendario vigente era el Juliano y no el Gregoriano que se implantó en el año 1582 para corregir los errores del primero. El desajuste del calendario Juliano era de 1 día cada 100 años, por tanto, sobre 1492 el error estaba en 9 días. Así que la fecha correcta del descubrimiento de América es sobre el 21 de octubre de 1492 (¡aunque para Colón seguía siendo 12 de octubre!).
Para saber más:
Operaciones con fechas y horas. Calendarios.
Obtener la diferencia de días entre dos fechas.
¿Colón ‘descubrió’ América un 12 o un 20 de octubre?

Deja una respuesta