Skip to content
Search

Leap year

lastmod 2025-05-18created 2025-05-181 edits

A leap year is a year into which an extra day or month is inserted to keep the calendar in line with the actual solar year. Because the solar year is not divisible by a whole number of days, and the Moon's orbital period differs from the Earth's, solar calendars correct for this by inserting a day (leap day) and lunisolar calendars by inserting a month (leap month) at appropriate times.

In solar calendars it usually refers to a year containing a leap day; in that case 01 year has 366 days, and that is a leap year. Since the Earth takes 365 days, 5 hours, 48 minutes, and 46 seconds to go around the Sun, solar calendars collect the time beyond 365 days and add one day by inserting February 29 once every 04 years. In lunar calendars, since a common year is 354 days, a leap month is inserted at a rate of 7 times in 19 years to align the seasons with the calendar months, keeping the year at 12 months. A year that is not a leap year is called a common year.

Leap years in the solar calendar correspond to the years of the Rabbit, Goat, and Pig among the 12 earthly branches. Among the sexagenary cycle, Gyeongja, Gyeongjin, and Gyeongsin years are sometimes not leap years, while Imja, Gapja, Byeongja, Muja, Imjin, Gapjin, Byeongjin, Mujin, Imsin, Gapsin, Byeongsin, and Musin years are always leap years. Also, when February 29 is included, from January 1 of the leap year until December 31 of the following common year, the days of the week differ by two from the previous year. For example, if January 1, 2024 is a Monday, February 29 pushes the days of the week by two, skipping Tuesday, so March 1, 2025 and February 28, 2026 fall on a Saturday. Because of February 29, January has the same or similar days of the week as April and July, and likewise March shows the same or similar pattern as September and December of the previous year.

Checking for a leap year in three instructions

Overview and problem statement

  • A function that determines leap years for years 0 to 102499 using only 3 CPU instructions
    • The actual function used has the form ((y * 1073750999) & 3221352463) <= 126976
  • Explains the principle, operation, and practical usefulness of this bit-twiddling technique

The traditional leap year check

  • Leap year checks are usually implemented with division (modulo) and conditional branches
  • Checks whether the year is divisible by 4, not divisible by 100, and divisible by 400

Example code:

if ((y % 4) != 0) return false  
if ((y % 100) != 0) return true  
if ((y % 400) == 0) return true  
return false

Optimizing the standard approach

  • The (y % 100) check can be replaced with (y % 25), and the (y % 400) check with (y % 16)
    • This works because the year has already been divided by 4, so it can be changed to the 25 and 16 multiplication relationship
  • A magic constant turns the (y % 25) operation into a multiplication and comparison without division
    • e.g. it can be converted to x * 3264175145 > 171798691
  • Adding bitmasks, division by 4 or 16 can be replaced with (y & 3) or (y & 15)
  • Compilers automate these transformations, but they can also be applied by hand in other languages

Branchless implementation

It can also be converted to a branchless form:

return !(y & ((y % 25) ? 3 : 15))

This approach suits shortening code, as in code golf (coding golf)

See also

  • year

Favorite site

author Zer0 sitemap