DEV Community

Baltasar García Perez-Schofield
Baltasar García Perez-Schofield

Posted on • Edited on

Python: ¡Feliz año bisiesto!

Si... estás relajado, revisando la red de redes, y entonces, probablemente debido a esta fecha tan señalada, aparece el anuncio: calendario perpetuo. Entonces te echas a reir y piensas filosóficamente en el pasado, cuando desaparecieron semanas e incluso meses enteros. O el efecto 2000.

Agenda electrónica

Los misterios del calendario son uno de esas maldiciones que el programador debe sufrir en su vida profesional (otro son los husos horarios). Hoy en día, las cosas han mejorado mucho, y todos los lenguajes de programación como Python proporcionan soporte de fecha y hora que incluso nos permiten avanzar y retrasar uno o varios días. ¡Una verdadera bendición para programar aplicaciones como la famosa práctica de la gestión del videoclub durante la carrera!

Cinta VHS para vídeo

¿Cómo? ¿Que qué es un videoclub? Mmm... madre mía qué mayor soy. Claro, hoy en día vemos las películas en nuestras plataformas de streaming, pero hace años uno iba a una tienda, cogía la película en DVD (incluso antes, en VHS), la metía en su reproductor y... sí, sí, DVD para vídeo... ¡Pues claro que, hace años, había cassettes para vídeo...! Uff... creo que me estoy yendo por los cerros de Úbeda. Prometo concentrarme si no preguntas más.

El caso es que era necesario comprobar si el usuario devolvía la película a tiempo o no. Pongamos que un cliente tenía tres días para devolver la película. Entonces, era necesario restar la fecha actual de la fecha de alquiler para encontrar el número real de días pasados...

En un primer momento, si tenemos que restar el 15 de abril del 20 de abril, no hay mayor problema. Claro que la cuestión empeora si las fechas involucran el comienzo o final de un mes determinado.

Bueno, no es tan complicado. Podemos hacernos una tabla como la que sigue.

Ene Feb Mar Abr May Jun Jul Ago Sep Oct Nov Dic
31 28 31 30 31 30 31 31 30 31 30 31

Genial. Con esto incluso en un lenguaje de programación como C podemos tener un vector con el máximo de días para cada mes, y así resolver la papeleta.

int max_dias[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
Enter fullscreen mode Exit fullscreen mode

En Python es todavía más fácil.

max_dias = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
Enter fullscreen mode Exit fullscreen mode

Pues problema resuelto... ¡no era para tanto!

Hasta que Pepito Grillo asoma por una esquina de tu mente y te pregunta... ¿y qué pasa si el año es bisiesto?

Ah... los años bisiestos. Resulta que nuestro calendario actual establece que los años tienen un total de 365 días. Genial.

Traslación de la tierra

Bueno, no tan genial. En realidad, resulta que el tikismikis de nuestro planeta gira alrededor del sol en 365 días y 6 horas. Como buenos informáticos podemos en un principio despreciar e ignorar esas seis horas, pero un rápido cálculo nos dice que estaríamos perdiendo un día entero... cada cuatro años. Y de ahí el año bisiesto, que se introduce como el 29 de febrero.

Y aquí viene lo bueno. ¿Cómo sabemos si un año es bisiesto? Pues tiene que cumplir tres sencillas reglas:

  • Ser múltiplo de 4
  • No ser múltiplo de 100.
  • A no ser que aún siendo múltiplo de 100, lo sea de 400.

Podemos realizar una primera versión del cálculo así:

def es_bisiesto(anno: int) -> bool:
    return (anno % 4 == 0
       and (anno % 100 != 0
         or anno % 400 == 0))
Enter fullscreen mode Exit fullscreen mode

El código es bastante sencillo e incluso bastante legible, pero podemos hacerlo todavía más legible de esta manera:

def es_bisiesto(anno: int) -> bool:
    divisible_4 = anno % 4 == 0
    divisible_100 = anno % 100 = 0
    divisible_400 = anno % 400 = 0

    return (divisible_4
       and (not divisible_100
         or divisible_400))
Enter fullscreen mode Exit fullscreen mode

De esta manera, podíamos crear una función restar_fechas() con una cierta confianza.

Pero hoy en día no es necesario todo esto, porque podemos restar fechas empleando la librería estándar.

from datetime import datetime


fecha1 = datetime(2024, 2, 20)
fecha2 = datetime(2024, 3, 2)

print(f"Son {fecha2 - fecha1} días en 2024")

fecha1 = datetime(2023, 2, 20)
fecha2 = datetime(2023, 3, 2)

print(f"Son {fecha2 - fecha1} días en 2023")
Enter fullscreen mode Exit fullscreen mode

El programa mostrará una salida como esta:

Son 11 00:00:00 días en 2024
Son 10 00:00:00 días en 2024
Enter fullscreen mode Exit fullscreen mode

Porque efectivamente, este 2024 es bisiesto. ¡Yupi!

Top comments (0)