Check Leap Year in JavaScript

Beginner
⏱️ 8 min read
📚 Updated: May 2026
🎯 2 Code examples + Try it
Gregorian

What you’ll learn

  • The Gregorian leap rule: divisible by 4, except most centuries, unless divisible by 400.
  • A compact isLeapYear predicate with clear && / || structure.
  • Printing every leap year in 2024–2050 (matching the reference output) plus a live preview.

Overview

Leap years keep the civil calendar aligned with the tropical year by inserting an extra day (February 29). The decision rule is pure integer modular arithmetic—ideal for a short conditional chain.

Two programs

2024 single check and 2024–2050 listing.

Live preview

Integer years in a safe range; same predicate as the tutorial scripts.

Rigor

Century vs quadricentennial cases and adoption caveats in the FAQ.

Prerequisites

The remainder operator %, boolean && and ||, and for loops.

  • console.log, Number.isSafeInteger.
  • Operator precedence: % binds tighter than ===; parentheses keep the intent obvious.

What is a leap year?

In the Gregorian calendar, a year is a leap year if February has 29 days. The arithmetic rule fixes the drift of a pure 365-day year.

Every year divisible by 4 is a leap candidate; century years (% 100 === 0) are ruled out unless they are divisible by 400.

2024 %4, not %100
1900 %100, not %400
2000 %400

Predicate

Let L(y) be true iff (y mod 4 = 0 ∧ y mod 100 ≠ 0) ∨ (y mod 400 = 0). Then L(y) is the standard proleptic Gregorian leap-year predicate.

2024

2024 mod 4 = 0 and 2024 mod 100 = 24 ≠ 0, so L(2024) holds.

Intuition

2024 Leap
Rule
quadrennial, not a century exception
2021 Common
Rule
2021 mod 4 = 1

Takeaway: divisibility by 4 is necessary but not sufficient once centuries enter the picture.

Live preview

Integer years in a reasonable safe range (this widget uses |y| ≤ 1000000).

Try 2000, 1900, or 2021.

Live result
Press “Check leap”.

Algorithm

Goal: evaluate the Gregorian leap predicate for an integer year.

Quadrennial test

Check year % 4 === 0. If false, the year is common.

Century refinement

If year % 100 === 0, require year % 400 === 0 to remain leap; otherwise the century exception applies.

📜 Pseudocode

Pseudocode
function is_leap_year(y):
    return (y mod 4 = 0 and y mod 100 != 0) or (y mod 400 = 0)
1

Single year: 2024

Same condition as the reference, using isLeapYear and console.log.

JavaScript
function isLeapYear(year) {
  return (
    (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0
  );
}

const year = 2024;

if (isLeapYear(year)) {
  console.log(year + " is a leap year.");
} else {
  console.log(year + " is not a leap year.");
}
Try it Yourself

Explanation

Short-circuiting && and || match the usual truth table; parentheses mirror the prose rule.

2

Leap years in [2024, 2050]

Matches the reference bounds and output line. Prints the header, then space-separated leap years, then a newline.

JavaScript
function isLeapYear(year) {
  if (
    (year % 4 === 0 && year % 100 !== 0) ||
    year % 400 === 0
  ) {
    return true;
  }
  return false;
}

const startYear = 2024;
const endYear = 2050;

console.log(
  "Leap years in the range " + startYear + " to " + endYear + ":"
);

const parts = [];
for (let y = startYear; y <= endYear; y++) {
  if (isLeapYear(y)) {
    parts.push(String(y));
  }
}
console.log(parts.join(" "));
Try it Yourself

Explanation

Leap years spaced by 4 until a century boundary; 2100 would break the pattern, but this interval stops at 2050.

Alternatives

Lookup tables. For a fixed window (like a UI calendar), precompute leap flags once.

Date libraries. Production systems often delegate to Date / platform APIs after validating components.

Interview: recite the 4 / 100 / 400 rule cleanly; mention real-world adoption only if asked.

❓ FAQ

A year is a leap year if it is divisible by 4, except years divisible by 100, unless they are also divisible by 400. Equivalently: leap iff (y%4==0 && y%100!=0) || (y%400==0).
Yes. 2000 is divisible by 400, so it is a leap year even though it is divisible by 100.
No. 1900 is divisible by 100 but not by 400, so it is a common year.
No. Adoption dates differ by country, and other calendars use different rules. This page uses the usual proleptic Gregorian arithmetic for integer years.
Historical numbering is messy; in code, test your product rule for negative y because JavaScript remainder follows the sign of the dividend. This tutorial keeps examples to typical positive civil years.
A single test is O(1) arithmetic. Scanning a year range [a,b] costs O(b - a + 1) with O(1) extra space.

🔄 Input / output examples

Change year in Example 1 or startYear / endYear in Example 2.

YearLeap?
2024Yes
2021No
2000Yes
1900No

Edge cases and pitfalls

The predicate is only part of a full date library; validating month/day and time zones is separate work.

400

Quadricentennial leap

2400 will be leap; 2200 will not.

BC

Astronomical year 0

Do not mix astronomical 0 with historical 1 BC without a clear convention.

Range

start > end

Swap bounds or guard the loop to avoid empty or inverted scans.

Types

Number safety

Civil years fit easily in safe integers; widen only if you embed years in packed timestamps.

⏱️ Time and space complexity

TaskTimeExtra space
One yearO(1)O(1)
Range [a, b]O(b - a + 1)O(1)

No auxiliary memory is required beyond loop indices.

Summary

  • Rule: (y%4===0 && y%100!==0) || (y%400===0).
  • Code: one boolean function plus a simple range loop for listings.
  • Watch-outs: Gregorian adoption history, negative years with %, and consistent range prose.
Did you know?

The Julian calendar had a leap every four years without the century exception. The Gregorian reform (1582 in several countries) dropped 10 days and refined the rule so years like 1900 are common years while 2000 stays a leap year.

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

8 people found this page helpful