2026ๅนด6ๆœˆ14ๆ—ฅ

The $10,000 Bug: How a Week Number Miscalculation Broke Our Entire Reporting Pipeline

I thought I knew how to get the week number in Python. Then my boss sent me a Slack message at 11pm on a Sunday: "Every Q4 report is showing Q1 data. Fix it."

The Slack Message I'll Never Forget

It was December 2025. I was wrapping up a quiet Sunday evening โ€” dinner was done, the kids were in bed โ€” when my phone lit up. My boss, the head of data engineering, had sent a Slack message. Not a "hey, when you get a chance" message. A "we need this fixed tonight" message.

"The executive quarterly reports went out this afternoon. Every single one of them shows incorrect quarter-to-date revenue. The numbers are shifted by one week. The VP of sales just called the CFO. The CFO just called me. I'm calling you."

My stomach dropped. Three weeks earlier, I'd written a Python pipeline that aggregated weekly sales data into quarterly buckets. It had been running fine. Or so I thought. The code that determined which quarter each week belonged to? About 12 lines. The bug? About 3 characters.

The Code That Looked Perfectly Fine

Here's roughly what I'd written:

from datetime import date

def get_quarter(week_num):
    """Map ISO week number to fiscal quarter. Q1 = weeks 1-13, Q2 = 14-26, etc."""
    if week_num <= 13:
        return "Q1"
    elif week_num <= 26:
        return "Q2"
    elif week_num <= 39:
        return "Q3"
    else:
        return "Q4"

# Main pipeline
today = date.today()
week_num = today.isocalendar()[1]  # โ† This line is the problem
quarter = get_quarter(week_num)

Looks reasonable, right? Nothing obviously wrong. The problem is subtle โ€” and if you don't understand ISO 8601 week numbering, you'll write this exact bug too. Give it a moment. Can you spot the issue?

๐Ÿ” Take 30 seconds: What's actually wrong with today.isocalendar()[1] in December 2025? Think about what "year" the last week of December belongs to under ISO rules.

The ISO 8601 Trap: A Week Can Belong to a Different Year

ISO 8601 has one rule that changes everything: the first week of the year is the week that contains January 4th. Or, equivalently: the first week is the one that contains the first Thursday of the year. Or: the first week is the one where the majority of its days (4 or more) fall in the new year.

All three definitions mean the same thing. And the consequence is this: the last few days of December can belong to week 1 of the next year. The first few days of January can belong to the last week of the previous year.

In December 2025, the dates December 29, 30, and 31 all fell into ISO week 1 of 2026. My code was calling date.today().isocalendar()[1], getting back a 1, and routing every transaction from those days into Q1. But in the fiscal calendar, those days still belonged to Q4 of 2025.

Why date.isocalendar() Follows the ISO Rule (and Why Most Developers Miss It)

Python's datetime.date.isocalendar() returns a tuple: (ISO_year, ISO_week, ISO_weekday). The key word is ISO_year. It's not the same as the calendar year. Let's look at a concrete example:

>>> from datetime import date
>>> dec31 = date(2025, 12, 31)
>>> dec31.isocalendar()
(2026, 1, 3)  # ISO year: 2026, ISO week: 1, ISO weekday: 3 (Wednesday)
>>> dec31.year
2025           # Calendar year: 2025

>>> jan1 = date(2025, 1, 1)
>>> jan1.isocalendar()
(2025, 1, 3)  # ISO year: 2025, ISO week: 1
>>> jan1.year
2025           # Both agree โ€” no issue here

On December 31, 2025, isocalendar() said "week 1 of 2026." But I was using the calendar year to determine the fiscal quarter. That mismatch โ€” ISO week number paired with calendar year โ€” is what broke everything.

The Same Bug in JavaScript, Java, and Every Other Language

This isn't just a Python problem. Every language has an equivalent footgun:

// JavaScript โ€” no native ISO week, but libraries have the same trap
const dayjs = require('dayjs')
const week = dayjs('2025-12-31').isoWeek()   // 1 (belongs to 2026!)
const year = dayjs('2025-12-31').year()       // 2025
// If you pair week=1 with year=2025, you get wrong results

// Java โ€” WeekFields.ISO vs. Chronofield
import java.time.LocalDate;
import java.time.temporal.WeekFields;
import java.util.Locale;

LocalDate dec31 = LocalDate.of(2025, 12, 31);
int week = dec31.get(WeekFields.ISO.weekOfYear());  // 1 (belongs to 2026!)
int year = dec31.getYear();                          // 2025
// Again: pairing week=1 with year=2025 destroys your data

// Even SQL has it
SELECT WEEKOFYEAR('2025-12-31');  -- MySQL: 53 (US mode), 1 (ISO mode)
SELECT EXTRACT(WEEK FROM DATE '2025-12-31');  -- PostgreSQL: depends on config!

The pattern is the same everywhere: ISO week numbers are designed for the ISO year, not the calendar year. If you use them with the calendar year, you'll get wrong results whenever a year boundary doesn't line up with a week boundary.

The Right Way, in Practice

If you're building any kind of weekly reporting, you need to decide which week numbering system you're using, document it explicitly, and then stick to it. Here's the reliable approach:

from datetime import date, timedelta

def get_iso_week_and_year(d):
    """
    Return (ISO_year, ISO_week) correctly.
    ALWAYS use isocalendar() for BOTH values โ€” never mix with .year.
    """
    iso_year, iso_week, _ = d.isocalendar()
    return iso_year, iso_week

def get_quarter_from_date(d):
    """Map a date to its fiscal quarter using the ISO week and ISO year together."""
    iso_year, iso_week = get_iso_week_and_year(d)
    # Now the mapping is correct because iso_year matches iso_week
    if iso_week <= 13:
        return iso_year, "Q1"
    elif iso_week <= 26:
        return iso_year, "Q2"
    elif iso_week <= 39:
        return iso_year, "Q3"
    else:
        return iso_year, "Q4"

# Test on the tricky dates
test_dates = [
    date(2025, 12, 31),  # ISO: 2026-W01
    date(2026, 1, 1),    # ISO: 2026-W01
    date(2026, 1, 5),    # ISO: 2026-W02 (Monday of W02)
]

for d in test_dates:
    iso_y, iso_w = get_iso_week_and_year(d)
    fy, fq = get_quarter_from_date(d)
    print(f"{d}: ISO {iso_y}-W{iso_w:02d} โ†’ Fiscal {fq} {fy}")

The output:

2025-12-31: ISO 2026-W01 โ†’ Fiscal Q1 2026
2026-01-01: ISO 2026-W01 โ†’ Fiscal Q1 2026
2026-01-05: ISO 2026-W02 โ†’ Fiscal Q1 2026

All three dates now map to the same fiscal period. No more quarter-boundary confusion. The rule is simple: if you're using ISO week numbers, use ISO year. Never mix ISO week with calendar year.

How I Fixed It at 2am (and What It Actually Cost)

That Sunday night, I wrote a backfill script that recalculated every affected record using the correct (ISO_year, ISO_week) pair. The pipeline re-ran in about 45 minutes. The numbers were corrected by Monday morning.

But the damage was done. The executive team had already seen wrong numbers. The VP of sales had presented incorrect quarterly projections to the board. Trust in the data team took a hit that took months to rebuild. Estimated cost: between our wasted weekend hours, the time execs spent in emergency meetings, and the credibility loss, my team lead put it at roughly $10,000.

All from three characters of code that looked totally fine in code review.

๐Ÿ’ก The real lesson: Week numbers are not a trivial formatting concern. They're a data integrity concern. Every time you write code that deals with weeks, you're making an implicit choice about which week numbering system to use โ€” and if you don't explicitly communicate that choice to the rest of your system (and your team), you're building a time bomb.

Three Rules I Now Live By

  1. Never store a week number without its corresponding year. Week 1 could mean "week 1 of 2025" or "week 1 of 2026." Without the year, it's ambiguous. Always store them as a pair: (2025, 52) or (2026, 1).
  2. Use ISO year with ISO weeks. Always. If your week number came from isocalendar() or WEEKNUM(date, 21) in Excel, pair it with the ISO year. Not the calendar year.
  3. Add a comment even when it seems obvious. My original get_quarter() function had no comment explaining which week system it expected. One line โ€” # Expects ISO week numbers, paired with ISO year โ€” would have made the mismatch obvious during review.

I've since seen variations of this bug in at least four different codebases, across three companies. It's not clever or exotic. It's just the mundane kind of bug that happens when a standard (ISO 8601) says one thing, and human intuition (December = old year) says another.

Use the week number calculator if you need a quick reference for any date. And if you're writing code that touches week numbers โ€” go look at it right now. Check whether you're mixing ISO weeks with calendar years. It might save you a 2am Slack message.

[ Google AdSense โ€” In-Article Ad ]