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.