Determine, count, and list leap years in Python
In Python, the calendar
module provides functions to determine if a year is a leap year and to count leap years in a specified period.
See the following article on how to create a text or HTML calendar with the calendar
module.
The calendar
module is included in the standard library, so no additional installation is required.
The algorithm for leap years
The algorithm for determining a leap year in the Gregorian calendar is represented by the following pseudocode:
if (year is not divisible by 4) then (it is a common year)
else if (year is not divisible by 100) then (it is a leap year)
else if (year is not divisible by 400) then (it is a common year)
else (it is a leap year)
Determine if a year is a leap year: calendar.isleap()
Use calendar.isleap()
to determine if a year is a leap year.
import calendar
print(calendar.isleap(2019))
# False
print(calendar.isleap(2020))
# True
print(calendar.isleap(1900))
# False
print(calendar.isleap(2000))
# True
The source code for calendar.isleap()
is as follows, using the modulo operator %
and logical operators and
and or
.
def isleap(year):
"""Return True for leap years, False for non-leap years."""
return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
Count leap years in a specified period: calendar.leapdays()
Use calendar.leapdays()
to count leap years in a specified period.
This function takes two arguments, y1
and y2
, and counts leap years from y1
(inclusive) to y2
(exclusive).
import calendar
print(calendar.leapdays(2019, 2030))
# 3
print(calendar.leapdays(2019, 2020))
# 0
List leap years in a specified period
To list leap years in a specified period, use calendar.isleap()
as a condition in list comprehension.
import calendar
print([y for y in range(2019, 2030) if calendar.isleap(y)])
# [2020, 2024, 2028]
print([y for y in range(2000, 2020) if calendar.isleap(y)])
# [2000, 2004, 2008, 2012, 2016]
Note that in range(start, end)
, end
is not included.
Determine if a datetime
or date
object is a leap year
Python's standard library includes the datetime
module for handling dates and times.
The datetime
module provides datetime.datetime
for both date and time, and datetime.date
for dates only.
Both datetime.datetime
and datetime.date
have the year
attribute. To determine if the year of a datetime.datetime
or datetime.date
object is a leap year, pass its year
attribute to calendar.isleap()
.
import calendar
import datetime
dt = datetime.datetime(2019, 1, 1, 10, 10, 10)
print(dt)
# 2019-01-01 10:10:10
print(calendar.isleap(dt.year))
# False
d = datetime.date(2020, 1, 1)
print(d)
# 2020-01-01
print(calendar.isleap(d.year))
# True
For example, you can define the following function. The argument can be either datetime.datetime
or datetime.date
.
def isleap_datetime(dt):
return calendar.isleap(dt.year)
print(dt)
# 2019-01-01 10:10:10
print(isleap_datetime(dt))
# False
print(d)
# 2020-01-01
print(isleap_datetime(d))
# True
If you prefer not to use the calendar
module, here is an alternative way.
def isleap_datetime2(dt):
return dt.year % 4 == 0 and (dt.year % 100 != 0 or dt.year % 400 == 0)
print(dt)
# 2019-01-01 10:10:10
print(isleap_datetime2(dt))
# False
print(d)
# 2020-01-01
print(isleap_datetime2(d))
# True