Q&A library Python

How do I work with business days and skip weekends in pandas?

Python Advanced business-daysdatetimeoffsets

Short answer

Use bdate_range for a range of working days and the BDay offset to add business days to a date. For real calendars you must supply the holidays yourself, because the defaults only skip weekends.

The short version

Use pd.bdate_range to build a range of business days (weekends excluded) and pd.offsets.BDay to shift a date forward by working days. Be aware that these only skip weekends by default. Public holidays are not excluded unless you supply a calendar.

A range of working days

import pandas as pd

days = pd.bdate_range("2021-01-01", "2021-01-10")
print(len(days))   # 6 , the weekend days are excluded

Ten calendar days contain six weekdays here, and bdate_range gives you exactly those.

Adding business days

pd.Timestamp("2021-01-01") + pd.offsets.BDay(1)   # 2021-01-04

The 1st was a Friday, so one business day later is the following Monday, not Saturday. A plain pd.Timedelta(days=1) would have given Saturday, which is the mistake this avoids.

The holiday trap

This is the important caveat. BDay and bdate_range skip Saturdays and Sundays, and nothing else. A public holiday falling on a Tuesday is still treated as a working day, so any "three working days from now" calculation will be wrong around holidays.

For a real calendar you must supply the holidays, using a custom business day offset.

from pandas.tseries.offsets import CustomBusinessDay

holidays = ["2021-01-01", "2021-12-27"]
cbd = CustomBusinessDay(holidays=holidays)

pd.Timestamp("2021-12-24") + cbd   # skips the holiday as well as the weekend

Because holidays differ by country, region and even by organisation, there is no correct default, which is why pandas does not guess. You must decide which calendar applies and provide it.

Counting working days between dates

To count the business days in a period, build the range and take its length, or use NumPy's dedicated function.

len(pd.bdate_range("2021-01-01", "2021-01-31"))

Again, this counts weekdays, not holidays, so subtract any holidays in the window if they matter.

Resampling by business day

resample accepts a business-day frequency, which is useful for financial series where weekends have no data.

series.resample("B").last()

Note this creates rows for weekdays that had no data, filling them with NaN. Decide whether to forward fill (carrying the previous day's value) or leave the gaps, because the two make different claims about what happened on a day with no observation.

The general lesson

Anything involving "working days" is a business rule, not a fact of the calendar, and it varies by organisation. Pandas gives you the machinery, but the holiday list is a decision you must make explicitly. Hard-coding weekends and forgetting holidays is the most common source of off-by-a-day errors in date arithmetic.

Enjoying these?

Go from piecing together answers to real fluency.

Our courses take you from looking things up to doing the work with confidence, step by step on real data.

Browse the courses