Python: ¡Feliz año bisiesto!
Tags: spanish, python, leapyear, learning
Published: 2024-02-29 20:21:26

---
title: Python: ¡Feliz año bisiesto!
published: true
description: Las maravillas del calendario.
tags: #spanish #python #leapyear #learning
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2024-02-29 18:48 +0000
---

Si... estás relajado, revisando la red de redes,  y entonces, probablemente debido a esta [fecha tan señalada](https://es.wikipedia.org/wiki/29_de_febrero), aparece el anuncio: [calendario perpetuo](https://es.wikipedia.org/wiki/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](https://es.wikipedia.org/wiki/Problema_del_a%C3%B1o_2000).

![Agenda electrónica](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ka5ttqfckj4uevzy4a4q.jpg)

Los misterios del calendario son uno de esas maldiciones que el programador debe sufrir en su vida profesional (otro son los [husos horarios](https://blog.chuidiang.org/2022/07/30/python-timezone-modulo-pytz/)). Hoy en día, las cosas han mejorado mucho, y todos los [lenguajes de programación como Python proporcionan soporte de fecha y hora](https://docs.python.org/3/library/datetime.html) 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](http://dis.um.es/~jnicolas/CSW/casoPracticoParaClaseVideoclub/CDUCasoPracticoVideoclub.pdf) durante la carrera!

![Cinta VHS para vídeo](https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/VHS-Video-Tape-Top-Flat_%28cropped%29.jpg/1024px-VHS-Video-Tape-Top-Flat_%28cropped%29.jpg)

¿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](https://es.wikipedia.org/wiki/DVD) (incluso antes, en [VHS](https://es.wikipedia.org/wiki/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.

```c
int max_dias[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
```

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

```python
max_dias = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
```

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

Hasta que [Pepito Grillo](https://es.wikipedia.org/wiki/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](https://es.wikipedia.org/wiki/Calendario_gregoriano) establece que los años tienen un total de 365 días. Genial.

![Traslación de la tierra](https://upload.wikimedia.org/wikipedia/commons/thumb/f/f0/Seasons1.svg/1024px-Seasons1.svg.png)

Bueno, no tan genial. En realidad, resulta que el tikismikis de [nuestro planeta gira alrededor del sol en 365 días y 6 horas] (y casi diez minutos más). 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í:

```python
def es_bisiesto(anno: int) -> bool:
    return (anno % 4 == 0
       and (anno % 100 != 0
         or anno % 400 == 0))
```

[El código es bastante sencillo](https://ideone.com/XYKq73) e incluso bastante legible, pero podemos hacerlo todavía más legible de esta manera:

```python
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))
```

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.

```python
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")
```

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

Porque efectivamente, este 2024 es bisiesto. ¡Yupi!