TheAlgorithms/Python · error · ValueError

Month must be between 1 - 12

Error message

Month must be between 1 - 12

What it means

Raised by zeller(date_input) in maths/zellers_congruence.py when the two-digit month parsed from date_input[0:2] is not in 1..12. The function slices characters positionally rather than tokenizing, so positions 0-1 are always interpreted as the month. A non-numeric month like '.2' instead raises 'invalid literal for int()' from int() before this check can run.

Source

Thrown at maths/zellers_congruence.py:95

        "1": "Monday",
        "2": "Tuesday",
        "3": "Wednesday",
        "4": "Thursday",
        "5": "Friday",
        "6": "Saturday",
    }

    convert_datetime_days = {0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6, 6: 0}

    # Validate
    if not 0 < len(date_input) < 11:
        raise ValueError("Must be 10 characters long")

    # Get month
    m: int = int(date_input[0] + date_input[1])
    # Validate
    if not 0 < m < 13:
        raise ValueError("Month must be between 1 - 12")

    sep_1: str = date_input[2]
    # Validate
    if sep_1 not in ["-", "/"]:
        raise ValueError("Date separator must be '-' or '/'")

    # Get day
    d: int = int(date_input[3] + date_input[4])
    # Validate
    if not 0 < d < 32:
        raise ValueError("Date must be between 1 - 31")

    # Get second separator
    sep_2: str = date_input[5]
    # Validate
    if sep_2 not in ["-", "/"]:
        raise ValueError("Date separator must be '-' or '/'")

View on GitHub (pinned to f5988cc097)

Solutions

  1. Convert your date to MM-DD-YYYY with strftime('%m-%d-%Y') which guarantees a valid, zero-padded month.
  2. If accepting user input, validate with datetime.strptime(s, '%m-%d-%Y') first so month range is enforced with a clear error.
  3. Document/require the MM-DD-YYYY order at every entry point that feeds this function.

Example fix

# before
zeller(f'{day:02d}-{month:02d}-{year}')  # DD-MM order -> month 31

# after
zeller(f'{month:02d}-{day:02d}-{year}')  # MM-DD-YYYY
Defensive patterns

Strategy: validation

Validate before calling

from datetime import datetime

def normalize_to_mmddyyyy(s: str) -> str:
    return datetime.strptime(s.strip(), '%m-%d-%Y').strftime('%m-%d-%Y')

Try / catch

try:
    day = zeller(s)
except ValueError as e:
    if 'Month' in str(e):
        s = swap_day_month(s)  # only if DD-MM input is expected
        day = zeller(s)
    else:
        raise

Prevention

When it happens

Trigger: Calling zeller('13-31-2010') (month 13); passing a date in DD-MM-YYYY order where the day exceeds 12, e.g. zeller('31-01-2010'); single-digit month written as '1-31-2010' shifts all positions and can produce a bogus month.

Common situations: Day/month transposition between US (MM-DD) and European (DD-MM) conventions; zero-padding omission ('1-31-2010' is 9 characters and also breaks positions); unvalidated free-text date fields.

Related errors


AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14). Data as JSON: /api/errors/0ef2216786f621db. Report an issue: GitHub.