A leap year in the Gregorian calendar follows this three-part rule: a year is a leap year if it's divisible by 4, EXCEPT for century years (divisible by 100), which must ALSO be divisible by 400 to be leap years. In code: `(year % 4 === 0 && year % 100 !== 0) || year % 400 === 0`.
Under this rule: 1896 was a leap year (divisible by 4, not a century year). 1900 was NOT a leap year (divisible by 100 but not 400). 2000 WAS a leap year (divisible by 400). 2100, 2200, and 2300 will not be leap years. 2400 will be. This three-part rule makes the Gregorian calendar year average 365.2425 days, which is accurate to within 26 seconds of the actual solar year.
Why the correction is necessary
The solar year — the time for Earth to orbit the Sun — is 365.2422 days. A calendar year of exactly 365 days drifts by 0.2422 days per year. Adding a leap day every 4 years overcorrects to 365.25 days, a drift of 0.0078 days per year in the other direction. Over 128 years, that excess adds up to a full day.
The century-year skip corrects most of that overcorrection: skipping a leap day every 100 years gives an average of 365.24 days, still 0.0022 days per year short. The 400-year exception adds back one day every 400 years, yielding 365 + 97/400 = 365.2425 days average, within 0.0003 days of the solar year. At that rate, the calendar won't be off by a full day for about 3,300 years.
Software bugs around year 1900 and 2000
The Y2K bug was widely discussed, but a less-known bug is the Year 1900 leap year bug in Microsoft Excel. Excel incorrectly treats 1900 as a leap year, which means dates in Excel's internal serial number system are off by 1 day for any date before March 1, 1900. This bug was preserved intentionally after release for compatibility with Lotus 1-2-3, which had the same bug. Excel's day 1 is January 1, 1900, and day 60 is incorrectly assigned to February 29, 1900.
The Y2K concern was precisely about century-year leap year exceptions: systems that stored years as two digits (e.g., '99' for 1999) would interpret '00' as 1900, which is NOT a leap year. A leap day calculation routine that worked correctly in 1999 might have failed on February 29, 2000 if it misidentified the year. Most systems were patched before 2000, but the edge case illustrates why explicit handling of the full Gregorian rule matters.