Find Leap Years from a Range of Years in JavaScript

October 21, 2025

javascript

A leap year is a year with 366 days instead of 365. Leap years occur every four years, with some exceptions based on century years. To find all leap years within a range, check each year against the leap year rules.

Leap Year Algorithm

A year is a leap year if it meets these conditions:

  • Divisible by 4
  • If divisible by 100, it must also be divisible by 400

For example, 2000 was a leap year (divisible by 400), but 1900 was not (divisible by 100 but not 400).

Find Leap Years with Filter

The filter() method can iterate through a range of years and return only the leap years.

js
1.function findLeapYears(startYear, endYear) {
2. const years = [];
3. for (let year = startYear; year <= endYear; year++) {
4. years.push(year);
5. }
6.
7. return years.filter(year => {
8. return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0);
9. });
10.}
11.
12.const leapYears = findLeapYears(2000, 2024);
13.// [2000, 2004, 2008, 2012, 2016, 2020, 2024]

Optimized Approach

A more efficient approach checks the leap year condition during the loop and only adds leap years to the array. This avoids creating an array of all years first, which saves memory when working with large ranges.

js
1.function findLeapYears(startYear, endYear) {
2. const leapYears = [];
3.
4. for (let year = startYear; year <= endYear; year++) {
5. if ((year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0)) {
6. leapYears.push(year);
7. }
8. }
9.
10. return leapYears;
11.}

Usage

js
1.const leapYears = findLeapYears(1896, 1904);
2.console.log(leapYears);

This will output:

js
1.// [1896, 1904]

Note that 1900 is not included because it's divisible by 100 but not by 400.

Helper Function for Checking Leap Years

Creating a reusable isLeapYear() function makes the code more readable.

js
1.function isLeapYear(year) {
2. return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0);
3.}
4.
5.function findLeapYears(startYear, endYear) {
6. const leapYears = [];
7.
8. for (let year = startYear; year <= endYear; year++) {
9. if (isLeapYear(year)) {
10. leapYears.push(year);
11. }
12. }
13.
14. return leapYears;
15.}
16.
17.// Check a single year
18.console.log(isLeapYear(2024)); // true
19.console.log(isLeapYear(2023)); // false
20.
21.// Find range of leap years
22.console.log(findLeapYears(2020, 2030));
23.// [2020, 2024, 2028]

Important Notes

This algorithm is correct for the Gregorian calendar (the standard civil calendar used worldwide). However, there are some important caveats:

  • Historical calendars: Before the Gregorian calendar was adopted (1582 onward, varying by country), many places used Julian calendar rules where every 4th year was a leap year with no 400-year exception. Years like 1700, 1800, and 1900 are leap years in the Julian calendar but not in the Gregorian calendar.
  • Revised Julian calendar: Some Orthodox churches use a different set of century rules. This code will not match those calculations.
  • JavaScript Date quirks: When using new Date(year, ...) with years 0-99, JavaScript interprets them as 1900-1999. The functions shown here use pure math and avoid this issue.
  • Very large ranges: For extremely large year ranges, you can optimize further by stepping through multiples of 4 instead of checking every year.

Found this helpful? Follow for more tips and tutorials