Zanam
Zanam

Reputation: 4807

Creating new holiday in pandas

I am using the following code to create my personalized holiday calendar:

class USTradingCalendar(AbstractHolidayCalendar):
    rules = [
        Holiday('NewYearsDay', month=1, day=1, observance=nearest_workday),
        USMartinLutherKingJr,
        USPresidentsDay,
        GoodFriday,
        USMemorialDay,
        Holiday('USIndependenceDay', month=7, day=4, observance=nearest_workday),
        USLaborDay,
        USThanksgivingDay,
        Holiday('Christmas', month=12, day=25, observance=nearest_workday)
    ]

I need to add USThanksgivingDayDayAfter as a new holiday to the above calendar. USThanksgivingDayDayAfter will be the next day (Friday) after observance of thanksgiving.

I am not really sure how to add USThanksgivingDayDayAfter to above class.

Upvotes: 0

Views: 710

Answers (1)

Jarad
Jarad

Reputation: 18893

This was quite hard to figure out. Some credit goes towards this answer.

At first, it seems as simple as seeing how USThanksgivingDay is defined.

USThanksgivingDay = Holiday('Thanksgiving', month=11, day=1,
                            offset=DateOffset(weekday=TH(4)))

That TH(4) part represents the fourth Thursday and is imported from dateutil.relativedelta. You might think just import FR (for Friday) and use the same offset rule. This won't work because if the fourth Thursday of November falls at the end of the week, the offset will get the next Friday creating a week gap in time.

The solution is to use a custom observance rule that you can define yourself. See example below:

from pandas.tseries.offsets import DateOffset
from pandas.tseries import holiday
from dateutil.relativedelta import TH
import pandas as pd

def custom_observance_rule(dt):
    """ Adds one day to Thanksgiving date """
    dt = dt + pd.offsets.DateOffset(weekday=TH(4))
    dt = dt + pd.Timedelta(days=1)
    return dt


class ExampleCalendar(holiday.AbstractHolidayCalendar):
    """ Example Calendar """
    rules = [
        holiday.USThanksgivingDay,
        # fourth Thursday of November + 1 day 
        holiday.Holiday(
            'USThanksgivingDayDayAfter',
            month=11, day=1,
            observance=custom_observance_rule
            )
        ]

cal = ExampleCalendar()
print(cal.holidays(return_name=True).sort_index())

This prints:

1970-11-26                 Thanksgiving
1970-11-27    USThanksgivingDayDayAfter
1971-11-25                 Thanksgiving
1971-11-26    USThanksgivingDayDayAfter
1972-11-23                 Thanksgiving
1972-11-24    USThanksgivingDayDayAfter
1973-11-22                 Thanksgiving
1973-11-23    USThanksgivingDayDayAfter
1974-11-28                 Thanksgiving
1974-11-29    USThanksgivingDayDayAfter
1975-11-27                 Thanksgiving
1975-11-28    USThanksgivingDayDayAfter
1976-11-25                 Thanksgiving
1976-11-26    USThanksgivingDayDayAfter
1977-11-24                 Thanksgiving
1977-11-25    USThanksgivingDayDayAfter
1978-11-23                 Thanksgiving
1978-11-24    USThanksgivingDayDayAfter
1979-11-22                 Thanksgiving
1979-11-23    USThanksgivingDayDayAfter
1980-11-27                 Thanksgiving
1980-11-28    USThanksgivingDayDayAfter
1981-11-26                 Thanksgiving
1981-11-27    USThanksgivingDayDayAfter
1982-11-25                 Thanksgiving
1982-11-26    USThanksgivingDayDayAfter
1983-11-24                 Thanksgiving
1983-11-25    USThanksgivingDayDayAfter
1984-11-22                 Thanksgiving
1984-11-23    USThanksgivingDayDayAfter
                        ...            
2016-11-24                 Thanksgiving
2016-11-25    USThanksgivingDayDayAfter
2017-11-23                 Thanksgiving
2017-11-24    USThanksgivingDayDayAfter
2018-11-22                 Thanksgiving
2018-11-23    USThanksgivingDayDayAfter
2019-11-28                 Thanksgiving
2019-11-29    USThanksgivingDayDayAfter
2020-11-26                 Thanksgiving
2020-11-27    USThanksgivingDayDayAfter
2021-11-25                 Thanksgiving
2021-11-26    USThanksgivingDayDayAfter
2022-11-24                 Thanksgiving
2022-11-25    USThanksgivingDayDayAfter
2023-11-23                 Thanksgiving
2023-11-24    USThanksgivingDayDayAfter
2024-11-28                 Thanksgiving
2024-11-29    USThanksgivingDayDayAfter
2025-11-27                 Thanksgiving
2025-11-28    USThanksgivingDayDayAfter
2026-11-26                 Thanksgiving
2026-11-27    USThanksgivingDayDayAfter
2027-11-25                 Thanksgiving
2027-11-26    USThanksgivingDayDayAfter
2028-11-23                 Thanksgiving
2028-11-24    USThanksgivingDayDayAfter
2029-11-22                 Thanksgiving
2029-11-23    USThanksgivingDayDayAfter
2030-11-28                 Thanksgiving
2030-11-29    USThanksgivingDayDayAfter
Length: 122, dtype: object

Upvotes: 1

Related Questions