How to calculate ISO week numbers and start and end dates in Python

Most ecommerce and marketing teams use ISO week reporting periods. Here's how to calculate ISO week numbers, week start and week end dates in Python.

How to calculate ISO week numbers and start and end dates in Python
Picture by Lukas, Pexels.
6 minutes to read

In ecommerce and marketing it’s relatively common to use ISO week numbers when reporting data. The ISO week system is a leap week calendar that forms part of the ISO 8601 date and time standard from the International Organization for Standardization or ISO.

The Gregorian calendar has a leap cycle that uses 97 leap days distributed across a 400-year period and contains a whole number 20871 weeks. This means the average year has 52.1775 weeks. By contrast, the ISO week number year, or ISO year, has either 52 or 53 full weeks, with 364 or 371 days, instead of the usual 365 or 366 in a Gregorian calendar year.

ISO weeks start on a Monday and end on a Sunday, which tends to be the common way that businesses measure their trading performance. In order to query databases or web analytics platforms to extract ecommerce or marketing data aligned to ISO weeks, you’ll need to be able to identify the start and end date for an ISO week, and work out the ISO week for a given date. Here’s how to do it in Python.

Install the packages

While you can calculate ISO week data manually, there’s a useful Python package called isoweek that simplifies the calculations. Open a Jupyter notebook and enter the command below to install the isoweek package.

!pip3 install isoweek
Requirement already satisfied: isoweek in /conda/envs/data-science-stack-2.5.1/lib/python3.7/site-packages (1.3.3)

Load the packages

Next, import the pandas package and the Week module from isoweek.

import pandas as pd
from isoweek import Week

Get the ISO week number for a date

First, we’ll tackle how to calculate the ISO week for a given date by creating a function we can use in other projects. We’ll pass a date string to this and use the Pandas to_datetime() function to convert it to a datetime object. Then we’ll use date.isocalendar() and return the second value 1 from the list to obtain an integer containing the ISO week number.

def get_iso_week_from_date(date):
    """Return the ISO week from a date.

    Args:
        date (str): Date

    Returns:
        week (int): ISO week
    """
    date = pd.to_datetime(date)
    return date.isocalendar()[1]
week = get_iso_week_from_date('2022-02-28')
week
9

Get the start date for an ISO week number

Next we’ll create a Python function to calculate the start date for a given ISO week using the year and the ISO week number. We’ll also add an optional argument for the date_format so you can either return the date as a string or a datetime object.

Since ISO weeks start on a Monday and end on a Sunday, we can calculate the start date for a given ISO week by passing the year and week arguments to Week() and appending .monday() to return that specific day. If we want the ISO week start date returned as a date string, i.e. YYYY-MM-DD, then we can pass in the optional formatter, such as %Y-%m-%d and we’ll get back the date in our chosen format.

def get_start_date_of_isoweek(year, week, date_format='datetime'):
    """
    Get the start date of the given ISO week using isocalendar()

    Args:
        year (int): Year, i.e. 2022
        week (int): Week, i.e. 34
        date_format (string): Format of the returned date, default is datetime

    Returns:
        datetime.date: Start date of the given ISO week
    """
    
    if date_format == 'datetime':
        return Week(year, week).monday()
    else:
        return Week(year, week).monday().strftime(date_format)
start = get_start_date_of_isoweek(2022, 9)
start
datetime.date(2022, 2, 28)
end = get_start_date_of_isoweek(2022, 9, '%Y-%m-%d')
end
'2022-02-28'

Get the end date for an ISO week number

The process for obtaining the end date in an ISO week is much the same, but instead of appending .monday(), we append .sunday(), since all ISO weeks end on a Sunday. We can then run the function to return either a datetime object containing the ISO week end date, or a date string in our chosen format.

def get_end_date_of_isoweek(year, week, date_format='datetime'):
    """
    Get the start date of the given ISO week using isocalendar()

    Args:
        year (int): Year, i.e. 2022
        week (int): Week, i.e. 34
        date_format (string): Format of the returned date, default is datetime        

    Returns:
        datetime.date: Start date of the given ISO week
    """
    
    if date_format == 'datetime':
        return Week(year, week).sunday()
    else:
        return Week(year, week).sunday().strftime(date_format)
end = get_end_date_of_isoweek(2022, 9)
end
datetime.date(2022, 3, 6)
end = get_end_date_of_isoweek(2022, 9, '%Y-%m-%d')
end
'2022-03-06'

Matt Clarke, Friday, March 18, 2022

Matt Clarke Matt is an Ecommerce and Marketing Director who uses data science to help in his work. Matt has a Master's degree in Internet Retailing (plus two other Master's degrees in different fields) and specialises in the technical side of ecommerce and marketing.