The 1900 Leap Year Lie — Python Bug Hunt

Inspired by the most famous deliberate bug in software: spreadsheets treat 1900 as a leap year (inherited from Lotus 1-2-3 and kept by Excel for…

  • Language: Python
  • Layer: Backend
  • Difficulty: Easy
  • Concepts: Dates, Leap Years
  • Modelled on: Excel / Lotus 1-2-3
  • Visible tests: 1900 was not a leap year; 2000 was a leap year; ordinary leap years still work
  • Reward: 50 XP for a complete fix

Briefing

Inspired by the most famous deliberate bug in software: spreadsheets treat 1900 as a leap year (inherited from Lotus 1-2-3 and kept by Excel for compatibility). Your date library copied the naive rule.

calendar_rules.py — the Gregorian rule has three clauses, not one.

Bug report

BUG-FEB29-1900 · Reported by: reporting pipeline

is_leap(year): divisible by 4, EXCEPT centuries, UNLESS divisible by 400.

  • 1900 -> False (a century, not divisible by 400)
  • 2000 -> True
  • 1996 -> True

Observed: every date after 1900-02-28 in imported sheets is shifted one day.

Logs

[import] serial 60 -> 1900-02-29 (a date that never existed)

The code as shipped

src/dates/calendar_rules.py (editable)

# Gregorian leap-year rule.

def is_leap(year):
    return year % 4 == 0

Open the hunt to edit the files, run the visible tests and submit against the hidden ones. More Python bug hunts.