Working with Business Days in pandas: Beyond BusinessMonthEnd.rule_code


BusinessMonthEnd in pandas.tseries.offsets

The BusinessMonthEnd class in pandas represents a date offset that increments dates to the last business day of the month. It's part of the pandas.tseries.offsets module, which provides tools for working with dates and time series data.

What rule_code refers to

  • In pandas offsets, the rule_code attribute is generally not directly exposed or used. It's likely an internal attribute that holds the logic behind the offset's behavior.

How BusinessMonthEnd works

  • Business days are typically defined as weekdays (Monday to Friday) excluding weekends and holidays (which can be customized).
  • When you use BusinessMonthEnd with a date, it adds or subtracts a specified number of months (default is 1) and ensures the resulting date falls on the last business day of that month.

For example:

from pandas.tseries.offsets import BMonthEnd

ts = pd.Timestamp('2024-05-20')  # A date in May 2024

# Move to the last business day of May 2024
ts + BMonthEnd()  # May result in '2024-05-31' (depending on holidays)

# Move two months forward to the last business day of July 2024
ts + 2 * BMonthEnd()  # May result in '2024-07-31' (depending on holidays)

Understanding the logic without the rule_code

While we can't see the exact code, we can understand the logic behind BusinessMonthEnd:

  1. It takes the current date and the number of months to move (n).
  2. It adds/subtracts n months to the date.
  3. It checks if the resulting date falls on a weekend or holiday (based on the defined calendar).
  4. If it's not a business day, it adjusts the date forward or backward to the nearest preceding/succeeding business day.


Example 1: Moving to the last business day with default settings

import pandas as pd
from pandas.tseries.offsets import BMonthEnd

# Set a date in June 2024
date = pd.Timestamp('2024-06-10')

# Move to the last business day of June 2024 (assuming no holidays)
last_business_day_of_june = date + BMonthEnd()

print(last_business_day_of_june)  # Output: 2024-06-30 (assuming no holidays in June)
import pandas as pd
from pandas.tseries.offsets import BMonthEnd

# Set a date in June 2024
date = pd.Timestamp('2024-06-28')  # A Friday close to the end of the month

# Define a holiday on June 30th, 2024 (a Sunday)
holiday = pd.Timestamp('2024-06-30')

# Create a custom calendar excluding the holiday
from pandas.tseries import holidays
custom_calendar = holidays.USFederalHolidays(observance=holidays.Easter)  # Base US calendar
custom_calendar = custom_calendar.add(holiday)  # Add the custom holiday

# Move to the last business day of June 2024 considering the holiday
last_business_day_of_june = date + BMonthEnd(calendar=custom_calendar)

print(last_business_day_of_june)  # Output: 2024-06-27 (since 30th is a holiday)
  • When we use BMonthEnd with this custom calendar, it considers June 30th a non-business day and moves the date to the preceding business day, which is June 27th, 2024.
  • We create a custom calendar using the holidays module and add the custom holiday to the existing US federal holiday list.
  • In the second example, we define a holiday on June 30th, 2024, which would normally be the last business day.


  1. Using BMonthEnd directly
    This is the recommended approach. BMonthEnd already encapsulates the logic for moving to the last business day of the month. You can simply use it with your date and optionally specify a custom calendar for handling holidays.

  2. Combining MonthEnd and CustomBusinessDay
    You can achieve a similar effect by using a two-step approach:

    • MonthEnd
      This moves the date to the last day of the month (including weekends and holidays).
    • CustomBusinessDay(n=0)
      This adjusts the date forward or backward by n business days (n=0 here means move to the closest business day). This allows you to define custom business days and holiday lists.
from pandas.tseries.offsets import MonthEnd, CustomBusinessDay

# Set a date in June 2024
date = pd.Timestamp('2024-06-10')

# Move to the last day of June (including weekends and holidays)
last_day_of_june = date + MonthEnd()

# Move to the closest business day (considering holidays)
last_business_day_of_june = last_day_of_june + CustomBusinessDay(n=0, calendar=custom_calendar)  # Same custom calendar as previous example

print(last_business_day_of_june)

Choosing the right approach

  • If you need more granular control over business day definitions and holiday handling, the combination of MonthEnd and CustomBusinessDay offers greater flexibility.
  • If you only need to move to the last business day of the month and don't need to customize business days, BMonthEnd is simpler and more efficient.