Cómo Saber si un Año es Bisiesto en Python

Cómo Saber si un Año es Bisiesto en Python

Este problema es un ejercicio clásico entre aquellas personas que comienzan su aprendizaje de programación. Es un buen ejercicio para practicar las instrucciones condicionales anidadas o bien las condiciones complejas con operadores booleanos. Te explico en este artículo varias maneras de resolver este problema y alguna cosa interesante más.

Una manera sencilla y compacta de saber si un año es bisiesto en Python, y suponiendo que la variable a contiene el año a comprobar, es utilizar la siguiente condición: not a % 4 and (a % 100 or not a % 400). Otra manera es usar la función isleap del módulo calendar.

Esta manera compacta puede ser un poco confusa para empezar. Vamos a ir evolucionando el ejercicio poco a poco para que te quede perfectamente claro.

Cuándo un año es bisiesto

Lo primero que tenemos que tener claro para la resolución de este ejercicio es cómo saber si un año es bisiesto. No vamos a explicar aquí por qué existen los años bisiestos o por qué se calculan de esta manera, no es nuestro objetivo.

Matemáticamente podemos saber si un año es bisiesto si este es múltiplo de 4. Si además es múltiplo de 100 no será bisiesto (ten en cuenta que 100 es múltiplo de 4 y por tanto cualquier número que sea múltiplo de 100 también es múltiplo de 4) a no ser que sea múltiplo de 400, que sí será bisiesto.

La verdad es que dicho de esta manera es un poco trabalenguas así que te lo resumo con una tabla, que te lo va a dejar clarísimo y, sobre todo, nos ayudará a resolver el ejercicio de manera más cómoda.

¿Múltiplo de 4?¿Múltiplo de 100?¿Múltiplo de 400?Es bisiestoEjemplos
NoNoNoNo2019, 1981
NoNo2020, 2012
NoNo1900, 2100
2000, 2400
Cómo saber si un año es bisiesto

¡Esto es otra cosa! ¿No? Seguimos…

Comprobar año bisiesto con varias condicionales

Pasemos entonces a la solución más directa que puede haber, aunque tal vez no sea la mejor. Como hay cuatro casos diferentes (las cuatro filas de la tabla) lo primero que viene a la mente es hacer cuatro condicionales distintas.

Tenemos que tener en cuenta que para calcular si un número es múltiplo de otro podemos usar el operador módulo o resto, que calcula el resto de la división entera entre dos números. Si el resto es 0 quiere decir que el divisor divide al dividendo y que por tanto el dividendo es múltiplo del divisor. También se dice que si un número a es múltiplo de un número b, b divide a. O que b es divisor de a. En Python el operador de módulo es %.

También es importante conocer los operadores booleanos and y or que nos permiten combinar varias condiciones sencillas en una sola compleja, así como el operador de comparación != que nos indica si dos valores son diferentes.

¡Veamos la solución!

año = 1980 #el año que queremos comprobar

if año % 4 != 0: #no divisible entre 4
	print("No es bisiesto")
elif año % 4 == 0 and año % 100 != 0: #divisible entre 4 y no entre 100 o 400
	print("Es bisiesto")
elif año % 4 == 0 and año % 100 == 0 and año % 400 != 0: #divisible entre 4 y 10 y no entre 400
	print("No es bisiesto")
elif año % 4 == 0 and año % 100 == 0 and año % 400 == 0: #divisible entre 4, 100 y 400
	print("Es bisiesto")

¡Cuidado! En este ejemplo, por claridad, estoy usando el nombre de variable año con caracteres no estándar debido a la «ñ». Esto puede ser fuente de problemas. La recomendación es evitar este tipo de símbolos en los identificadores que utilicemos a la hora de programar. Te sugiero como alternativa los nombres ano, anno o year.

Si te fijas, he encadenado las condicionales con elif a pesar de que todos los casos ya son excluyentes entre sí. Lo he hecho así por eficiencia del código.

Si pruebas a ejecutar ese código verás que funciona perfectamente con el año que prefieras. También puedes pedirle al usuario el valor del año si lo prefieres.

El problema de esta solución es que es bastante larga y repite mucho código en las condiciones, cosa que no es deseable. Como puedes ver hay condiciones sencillas que se repiten en varios casos, por ejemplo, ser múltiplo de 4. Para solucionar esto podemos utilizar condicionales anidadas.

Comprobar año bisiesto con condicionales anidadas

Como sabrás, las condicionales anidadas nos permiten ubicar una condicional dentro de otra y así ahorrarnos el tener que repetir una condición varias veces.

Esta que te presento aquí es la solución más popular que encontrarás en otros blogs y páginas de internet. La vemos:

año = 1980 # el año que queremos comprobar

if not año % 4:
	if not año % 100:     # divisible entre 4 y 100
		if not año % 400:  # divisible entre 4, 100 y 400
			print("Es bisiesto")
		else:              # divisible entre 4 y 100 y no entre 400
			print("No es bisiesto")
	else:                 # divisible  entre 4 y no entre 100
		print("Es bisiesto")
else:                    # no divisible entre 4
	print("No es bisiesto")

Con esto mejoramos la solución pero sigue siendo un poco difícil de leer y de seguir, así que vamos a seguir mejorándola. La idea es ahora utilizar una única condición.

Comprobar año bisiesto con una condicional

Si analizas la tabla que te presenté antes podrás llegar a la conclusión de que podemos resolver el ejercicio con una única condición. Pero para ello tenemos que combinar todas las condiciones en una sola más compleja.

En lenguaje natural podemos decir que un año es bisiesto si «es múltiplo de 4 y además no es múltiplo de 100 o lo es de 400. Siendo un poco más formales, pero solo un poco, y siendo A la condición de ser múltiplo de 4, B la condición de ser múltiplo de 100 y C la condición de ser múltiplo de 400 podemos decir que un año es bisiesto si se cumple que A y (no B o C).

Esa expresión es el resumen de la tabla de antes, así que vamos a implementarla:

año = 1980

if año % 4 == 0 and (año % 100 != 0 or año % 400 == 0):
	print("Es bisiesto")
else:
	print("No es bisiesto")

Como puedes ver este código resulta mucho más compacto, más fácil de leer e, incluso, con un aspecto más profesional.

Mejorando el código y creando una función

Para terminar de redondear nuestra solución vamos a aplicar dos modificaciones y además vamos a encapsular la solución en una función con un parámetro para poder invocarla cuando necesitemos.

La primera mejora consiste en eliminar las comparaciones == y !=. Pero, ¿podemos hacer esto? Pues claro. Python considera que cualquier número diferente de 0 es True y que el 0 es False. Así, de esta manera, y teniendo en cuenta que el operador % nos devuelve un número que se puede considerar un valor booleano, podemos hacer las siguientes sustituciones:

  • año % 4 == 0 por not año % 4.
  • año % 100 != 0 por año % 100.
  • año % 400 == 0 por not año % 400.

Esta mejora podemos aplicarla en cualquiera de las versiones que te he presentado aquí. Aplicada a la última versión la condición completa nos quedaría de la siguiente manera: not año % 4 and (año % 100 or not año % 400).

La segunda mejora consiste en usar el operador condicional ternario de Python que nos permitirá escribir la condición y el resultado en una sola línea. De esta manera, y aplicando estas dos mejoras, nos quedamos con el siguiente código:

año = 1980

print("Es bisiesto" if not año % 4 and (año % 100 or  not año % 400) else "No es bisiesto")

Ya lo ves, más compacto todavía. Solo nos queda ya ubicar ese código dentro de una función que reciba el año como parámetro y que nos devuelva un valor booleano diciéndonos si el año es bisiesto y poder procesar esa información como queramos. Ten en cuenta que al utilizar una función ya no necesitaremos el operador condicional ternario porque la propia condición es el resultado que queremos devolver en la función:

def es_bisiesto(año):
	return not año % 4 and (año % 100 or not año % 400)

¡Listo! Ahora sí que tenemos una función pequeña y preparada para comprobar si un año cualquiera es bisiesto.

Calcular todos los años bisiestos entre dos años dados

Vamos a usar esta función en otro ejercicio muy típico relacionado que es calcular todos los años bisiestos entre dos años dados. Por ejemplo, y para calcular todos los años bisiestos entre el año 1800 y el año 2020 podemos hacer lo siguiente:

def es_bisiesto(año):
	return not año % 4 and (año % 100 or not año % 400)


for año in range(1800, 2021):
	if es_bisiesto(año):
		print(año, end=' ')

Si no tienes demasiado clara la manera en que utilizo el for en este ejercicio junto con la función range te lo explico en este artículo sobre cómo obtener tablas de multiplicar en Python.

El resultado de la ejecución del código anterior es el siguiente:

1804 1808 1812 1816 1820 1824 1828 1832 1836 1840 1844 1848 1852 1856
1860 1864 1868 1872 1876 1880 1884 1888 1892 1896 1904 1908 1912 1916
1920 1924 1928 1932 1936 1940 1944 1948 1952 1956 1960 1964 1968 1972
1976 1980 1984 1988 1992 1996 2000 2004 2008 2012 2016 2020

Comprobar año bisiesto con el módulo calendar de Python

Finalmente, y si no es de tu interés el aprender a hacer un algoritmo que compruebe si un año es bisiesto o no y solo necesitas una manera cómoda y rápida de hacer dicha comprobación, debes saber que, como no podía ser de otra manera, Python ya incorpora una función que lo hace por nosotros.

Dentro del módulo calendar, que está destinado a realizar operaciones con fechas, existe una función llamada isleap, entre otras muchas, que hace exactamente lo mismo que la función es_bisiesto que te acabo de proponer más arriba. Para utilizarla basta con importar la función y utilizarla como queramos. Te lo muestro con el ejemplo anterior:

from calendar import isleap

for año in range(1800, 2021):
	if isleap(año):
		print(año, end=' ')

Espero que haya podido aclararte alguna cosa, por pequeña que sea, sobre el uso de condicionales y el cálculo de los años bisiestos. Con eso me doy por satisfecho.

La Hoja de Referencia de Python – ¡Gratis!

La Hoja de Referencia de Python - Código Pitón
Consigue trucos, consejos y actualizaciones y, por supuesto, la Hoja de Referencia de Python gratis.



Antes de suscribirte consulta aquí la Información Básica sobre Protección de Datos. Responsable de los datos: Laura Otero Moreira. Finalidad de la recogida y tratamiento de los datos personales: enviarte boletín informativo de Python y comunicaciones comerciales. Legitimación: tu consentimiento. Destinatarios: no se ceden a terceros. Los datos se almacenan en los servidores de marketing (MailRelay). Derechos: podrás ejercer tus derechos de acceso, rectificación, limitación y supresión de datos en info @ codigopiton.com así como presentar una reclamación ante una autoridad de control. Más información en nuestra política de privacidad, encontrarás información adicional sobre la recopilación y el uso de tu información personal, incluida información sobre acceso, conservación, rectificación, eliminación, seguridad y otros temas.