Skip to main content

Appendix C

if (year % 400 == 0) then
return LEAP_YEAR
else if (year % 100 == 0) then
return NOT_LEAP_YEAR
else if (year % 4 == 0) then
return LEAP_YEAR
else
return NOT_LEAP_YEAR

Implementation Examples​

C Language​

int is_leap_year(int year) {
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}

// Or a clearer version
int is_leap_year_verbose(int year) {
if (year % 400 == 0) {
return 1; // Divisible by 400: leap year
}
if (year % 100 == 0) {
return 0; // Divisible by 100 but not 400: common year
}
if (year % 4 == 0) {
return 1; // Divisible by 4 but not 100: leap year
}
return 0; // Otherwise: common year
}

Python​

def is_leap_year(year):
"""Determine if year is a leap year"""
return (year % 400 == 0) or (year % 4 == 0 and year % 100 != 0)

# Or use Python calendar module
import calendar
print(calendar.isleap(2000)) # True

JavaScript​

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

Java​

public static boolean isLeapYear(int year) {
return (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
}

// Or use Java 8+ GregorianCalendar
import java.util.GregorianCalendar;
boolean isLeap = GregorianCalendar.isLeapYear(2000);

Historical Leap Year Examples​

Recent Leap Years (21st Century)​

2000: Leap year ✅ (divisible by 400)
2001: Common year ❌
2002: Common year ❌
2003: Common year ❌
2004: Leap year ✅ (divisible by 4, not by 100)
2008: Leap year ✅
2012: Leap year ✅
2016: Leap year ✅
2020: Leap year ✅
2024: Leap year ✅
2028: Leap year ✅

Century Years (Special Cases)​

1600: Leap year ✅ (divisible by 400)
1700: Common year ❌ (divisible by 100 but not 400)
1800: Common year ❌ (divisible by 100 but not 400)
1900: Common year ❌ (divisible by 100 but not 400)
2000: Leap year ✅ (divisible by 400)
2100: Common year ❌ (divisible by 100 but not 400)
2200: Common year ❌
2300: Common year ❌
2400: Leap year ✅ (divisible by 400)

Days in Each Month​

Understanding leap years is crucial for determining days in each month:

def days_in_month(year, month):
"""Return number of days in specified year and month"""
days_per_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

if month == 2 and is_leap_year(year):
return 29
return days_per_month[month - 1]

# Examples
print(days_in_month(2000, 2)) # 29 (leap year February)
print(days_in_month(1900, 2)) # 28 (common year February)
print(days_in_month(2024, 4)) # 30 (April always 30 days)

Date Validation​

def is_valid_date(year, month, day):
"""Validate if date is valid"""
if month < 1 or month > 12:
return False

if day < 1:
return False

max_day = days_in_month(year, month)
if day > max_day:
return False

return True

# Tests
print(is_valid_date(2000, 2, 29)) # True (leap year)
print(is_valid_date(1900, 2, 29)) # False (common year)
print(is_valid_date(2002, 4, 31)) # False (April has only 30 days)

History of Leap Years​

Julian vs Gregorian Calendar​

Julian Calendar:

  • Introduced by Julius Caesar in 46 BC
  • Simple rule: leap year every 4 years
  • Average year length: 365.25 days
  • Problem: about 11 minutes longer than actual solar year

Gregorian Calendar:

  • Introduced by Pope Gregory XIII in 1582
  • Modified rule: century years must be divisible by 400
  • Average year length: 365.2425 days
  • Closer to actual solar year (365.2422 days)

Adoption of Gregorian Calendar​

Different countries adopted the Gregorian calendar at different times:

1582: Italy, Spain, Portugal
1752: Great Britain and colonies (including US)
1917: Russia
1923: Greece
 = 100 - 4 + 1 = 97)


def validate_rfc3339_date(year, month, day):
if year < 0 or year > 9999:
return False, "Year must be 0000-9999"

if month < 1 or month > 12:
return False, "Month must be 01-12"

if not is_valid_date(year, month, day):
max_day = days_in_month(year, month)
return False, f"Day must be 01-{max_day:02d} for {year}-{month:02d}"

return True, "Valid date"

print(validate_rfc3339_date(2000, 2, 29)) # (True, 'Valid date')
print(validate_rfc3339_date(1900, 2, 29)) # (False, '...')