Why leap years exist at all
The Earth takes about 365.2422 days to return to the same point in its orbit relative to the equinoxes — the mean tropical year. A calendar of exactly 365 days therefore runs fast by very nearly a quarter of a day every year, and the seasons slide steadily earlier through it. Add one day every fourth year and you have the Julian calendar's mean of 365.25 days, which is much better but still 0.0078 days too long.
That residue accumulates to roughly one day every 128 years, and by the sixteenth century the vernal equinox had drifted about ten days from the date the Church used to fix Easter. The Gregorian reform of 1582 fixed it by removing three leap days from every four centuries: century years are leap only when divisible by 400. The mean year becomes 146,097 / 400 = 365.2425 days, within 0.0003 days of the tropical year, an error of about one day in 3,300 years.
So the rule has three clauses and they must be read in order. A year divisible by 4 is leap, unless it is divisible by 100, unless it is also divisible by 400. That is why 1900 was a common year and 2000 was a leap year, and why 2100, 2200 and 2300 will all be common. Anyone whose date code was written after 1901 and tested before 2100 has never seen the exception fire, which is exactly why the century case keeps producing bugs.
A leap day is inserted as 29 February, which shifts the ordinal date of every subsequent day in that year by one — the reason the day of year calculator needs to know the leap status before it can convert anything.
The formula, one variable at a time
Testing a single year is three modulo operations. Y mod 4 = 0 admits it, Y mod 100 = 0 excludes it, Y mod 400 = 0 readmits it. Written as one expression: leap ⇔ (Y mod 4 = 0 and Y mod 100 ≠ 0) or Y mod 400 = 0.
Counting leap years across a span is where a closed form pays. Define f(n) = ⌊n/4⌋ − ⌊n/100⌋ + ⌊n/400⌋, the number of leap years from year 1 through year n. Each floor term counts the multiples of its divisor at or below n: the first adds every fourth year, the second removes every hundredth, the third puts back every four-hundredth. The count in a range is then the difference f(b) − f(a−1).
Subtracting f(a−1) rather than f(a) is deliberate and is the classic off-by-one in this calculation. Using f(a) would exclude the start year whenever the start year is itself a leap year, so the count for 2000 to 2000 would come out as zero instead of one.
Total days follow immediately: every year contributes 365 days and every leap year one more, so D = 365(b − a + 1) + leaps. The Julian version of everything is the same with only the first floor term, which is the whole difference between the two calendars expressed in one line of algebra.
Worked example: how many leap years and days in 1801-1900?
The nineteenth century is a good test because it contains a century year that is not leap, which is where intuition fails.
- Leap years up to 1900. ⌊1900/4⌋ = 475, ⌊1900/100⌋ = 19, ⌊1900/400⌋ = 4. So f(1900) = 475 − 19 + 4 = 460.
- Leap years up to 1800. ⌊1800/4⌋ = 450, ⌊1800/100⌋ = 18, ⌊1800/400⌋ = 4. So f(1800) = 450 − 18 + 4 = 436.
- Difference. 460 − 436 = 24 leap years in 1801-1900.
- Check it by counting. Every fourth year from 1804 to 1896 gives (1896 − 1804)/4 + 1 = 24. The candidate 1900 is excluded because it is divisible by 100 but not 400. The two methods agree.
- Years in the range. 1900 − 1801 + 1 = 100.
- Total days. 365 × 100 + 24 = 36,500 + 24 = 36,524 days.
Now run the same range under the Julian rule: ⌊1900/4⌋ − ⌊1800/4⌋ = 475 − 450 = 25 leap years and 36,525 days. The single day of difference is 1900 itself, and it is the entire correction the Gregorian reform applies in that century. Over a full 400-year cycle the same arithmetic gives 100 − 3 = 97 Gregorian leap years and 400 × 365 + 97 = 146,097 days.
Leap year rules and mean year lengths compared
| Calendar | Leap rule | Leap years per 400 yr | Days per 400 yr | Mean year (d) | Drift of 1 day in |
|---|---|---|---|---|---|
| No leap years | none | 0 | 146,000 | 365 | about 4 years |
| Julian | Y mod 4 = 0 | 100 | 146,100 | 365.25 | about 128 years |
| Gregorian | Y mod 4 = 0, not Y mod 100 = 0, unless Y mod 400 = 0 | 97 | 146,097 | 365.2425 | about 3,300 years |
Mean year = days per 400 years divided by 400. The drift column is 1 divided by the difference between that mean and 365.2422 days: 1/0.25 ≈ 4, 1/0.0078 ≈ 128, 1/0.0003 ≈ 3,300.
How to read the result
For any year from 1901 to 2099 the answer is simply whether the year divides by 4, because no century year falls in that window. Outside it, read the century clauses. If your year ends in 00 the answer hinges entirely on the 400 test, and the calculator shows all three modulo results as separate steps so you can see which clause decided it.
The next and previous leap year figures are usually four years away, but not across a skipped century. From 2099 the next leap year is 2104, not 2100, and from 1900 the previous one is 1896. Any code that computes “the next leap year” by rounding to a multiple of four is wrong exactly at those boundaries.
The range count includes both endpoints. If you want the number of leap days strictly between two dates rather than across whole years, that is a different question — a range from 1 March 2024 to 1 February 2028 contains one 29 February, not two, because the 2024 leap day had already passed. Use the age in days calculator when the boundaries are dates rather than years.
The total-days figure is exact for the Gregorian calendar as a mathematical object, but it is not always the number of days a country actually experienced. When a nation adopted the reform it deleted a block of dates: Catholic Europe skipped 5 to 14 October 1582, Britain and its colonies skipped 3 to 13 September 1752, and Russia did not switch until 1918. For historical spans that cross an adoption date, count the calendar the records were kept in.
Assumptions and common mistakes
- Stopping at the divisible-by-4 test. It is right 96 times in 100 and wrong at 1900, 2100, 2200 and 2300. Test suites written between 1901 and 2099 never expose it.
- Assuming 2000 proved the rule. 2000 is divisible by 400, so it took the exception to the exception and behaved like an ordinary leap year. It tested nothing.
- Using f(a) instead of f(a−1) for a range. This silently drops the start year whenever the start year is a leap year.
- Applying the Gregorian rule to dates before 1582. Doing so gives a proleptic date, which is fine for arithmetic but does not match what contemporary records say.
- Assuming every country changed calendars at the same time. Adoption spans 1582 to 1927, so the same instant can carry two different dates depending on the source.
- Treating a year of 366 days as 366 usable days for a rate. Interest conventions, payroll accruals and utilisation rates each have their own day-count basis, and several use a fixed 360 or 365 regardless.
The 400-year cycle repeats exactly
A Gregorian cycle of 400 years contains 146,097 days, and 146,097 divided by 7 is exactly 20,871. The number of days in the cycle is therefore a whole number of weeks, so the calendar repeats perfectly every 400 years: the same date falls on the same weekday and the whole pattern of leap years recurs. That is why 1 January 2000 and 1 January 2400 are both Saturdays, and it is the property that makes the day of week calculator reducible to arithmetic on a 400-year table. The Julian calendar has no such property, because 146,100 days is not a multiple of seven.
Related calculations and where the leap rule shows up
Leap status is an input to almost every calendar computation. The day of year calculator needs it to place dates after February. The Easter date calculator uses the Gregorian computus, whose solar and lunar corrections exist precisely because of the century rule. The Unix timestamp converter embeds it in the days-from-civil conversion, which is what lets epoch arithmetic stay exact across February in any year.
Astronomy sidesteps the whole question by counting days rather than dates. A Julian date is a continuous day number from 4713 BC with no months, no leap rule and no discontinuity at any calendar reform, which is why it is the standard for observation logs and ephemerides. Convert to it once and every interval becomes a subtraction.
Other calendars solve the same drift differently. The Revised Julian calendar used by several Orthodox churches makes a century year leap only when dividing by 900 leaves 200 or 600, giving a mean year of 365.2422 days — closer to the tropical year than the Gregorian. The Hebrew and Islamic calendars are lunisolar and lunar respectively, and insert whole months or single days on completely different cycles.
Key terms
- Tropical year
- The interval between successive passages of the Sun through the vernal equinox, about 365.2422 days. It is what a seasonal calendar is trying to track.
- Intercalation
- The insertion of an extra day or month into a calendar to keep it aligned with the astronomical year. A leap day is an intercalation.
- Proleptic Gregorian calendar
- The modern rule projected backwards before its 1582 introduction. Useful for arithmetic, but not what historical documents from those years say.
- Century year
- A year ending in 00. These are the only years where the Julian and Gregorian rules disagree, and three in every four of them are common years under the Gregorian rule.
