Skip to content

Quickstart

This is a hands-on lesson: by the end of it you will have written a small helper that turns any date into an ISO week label and builds the rolling window of weeks a weekly report needs.

Follow the steps in order and run every snippet. Each one builds on the previous one, and every output on this page is produced by actually running the code.

If you already know the library and are looking for a specific method, go to the API tour instead.

What you will build

A report_weeks helper that answers: "which ISO weeks does my 4-week report cover, and which calendar dates fall in each of them?"

Step 1: install the library

python -m pip install iso-week-date

Nothing else is needed for this lesson. See installation for the optional extras.

Step 2: turn a date into a week

Import IsoWeek and build one from a date:

from datetime import date

from iso_week_date import IsoWeek

reference_day = date(2026, 3, 10)
week = IsoWeek.from_date(reference_day)

print(week)
2026-W11

week is now an object, not a string, but it carries the canonical YYYY-WNN label. Its parts are available as integers:

print(week.year, week.week, week.quarter)
2026 11 1

Why not strftime?

You may be used to writing some_date.strftime("%Y-W%V"). That is subtly wrong at year boundaries: %Y is the calendar year while %V is the ISO week number, and the two disagree during the last and first days of a year. Why iso-week-date? shows the failure and explains it.

Step 3: ask the week which dates it covers

A week knows the seven dates it spans:

for day in week.days:
    print(day)
2026-03-09
2026-03-10
2026-03-11
2026-03-12
2026-03-13
2026-03-14
2026-03-15

If you only want the boundaries, ask for the nth day (1 is Monday, 7 is Sunday):

print(week.nth(1), "->", week.nth(7))
2026-03-09 -> 2026-03-15

And you can test membership with the in operator:

print(reference_day in week)
print(date(2026, 3, 16) in week)
True
False

Step 4: move between weeks

Adding an int to an IsoWeek moves it by that many weeks, and the year boundary is handled for you:

print(week + 1)
print(week - 13)
2026-W12
2025-W50

Subtracting two weeks gives you the distance between them as an int:

print(week - IsoWeek("2026-W08"))
3

This is the reason to use objects rather than strings: no conversion to date and back, and no arithmetic on the week number that breaks when a year has 53 weeks.

Step 5: build the report window

IsoWeek.range generates every week between two endpoints. Combine it with what you learned in step 4 to get the last four weeks:

window = tuple(IsoWeek.range(start=week - 3, end=week, inclusive="both", as_str=True))

print(window)
('2026-W08', '2026-W09', '2026-W10', '2026-W11')

as_str=True gives you plain strings, which is what you usually want for a report label or a dataframe column.

Step 6: go down to the day

When a week is too coarse, IsoWeekDate works the same way but with a weekday component, and int arithmetic moves it by days instead of weeks:

from iso_week_date import IsoWeekDate

day = IsoWeekDate.from_date(reference_day)

print(day, "| weekday:", day.weekday, "| its week:", day.isoweek)
print(day + 1)
2026-W11-2 | weekday: 2 | its week: 2026-W11
2026-W11-3

Step 7: put it together

def report_weeks(reference: date, n_weeks: int = 4) -> dict[str, tuple[date, date]]:
    """Map each ISO week label in the report window to its first and last calendar day."""
    last_week = IsoWeek.from_date(reference)
    weeks = IsoWeek.range(
        start=last_week - (n_weeks - 1), end=last_week, inclusive="both", as_str=False
    )
    return {w.to_string(): (w.nth(1), w.nth(7)) for w in weeks}


for label, (first, last) in report_weeks(date(2026, 3, 10)).items():
    print(f"{label}: {first} -> {last}")
2026-W08: 2026-02-16 -> 2026-02-22
2026-W09: 2026-02-23 -> 2026-03-01
2026-W10: 2026-03-02 -> 2026-03-08
2026-W11: 2026-03-09 -> 2026-03-15

That is a complete, correct weekly-report window in a handful of lines, with no strftime format strings and no manual year-boundary handling.

What you learned

  • IsoWeek.from_date and IsoWeekDate.from_date build objects from dates.
  • .year, .week, .quarter, .weekday and .isoweek expose the parts.
  • .days, .nth() and the in operator relate a week back to calendar dates.
  • int arithmetic moves by weeks on IsoWeek and by days on IsoWeekDate.
  • .range() generates windows, with as_str choosing between objects and strings.

Next steps