cphill
cphill

Reputation: 5914

Pandas Holiday Package Black Friday Offset

I am using the holidays package to build a calendar of my calendar holidays and I made an adjustment to account for "Black Friday" (Day after US Thanksgiving. Always a Friday) with a relative delta for the 4th week in November, which works for 2018 and 2020, but this year, it would be the 5th week in November, which would make my setup ineffective

Is there a better way to ensure that this value always falls on the Friday after Thanksgiving? I'm not sure whether it is best to use the holidays package list of holidays and use some pandas magic to offset based on those values and set the holiday or if there is a better date manipulation method to achieve this.

Here is my method:

self.append({datetime.date(datetime(year, 11, 1) + relativedelta(weekday=FR(+4))) : "Black Friday"}) # Adding Black Friday

Here is the full code:

import pandas as pd
import numpy as np
import calendar as cal
from datetime import *
from dateutil.relativedelta import *
import holidays

class CorporateHolidays(holidays.UnitedStates):
    def _populate(self, year):
        print(self)
        # Populate the holiday list with the default US holidays
        holidays.UnitedStates._populate(self, year)
        # Remove Holiday Date(s)
        self.pop(datetime.date(datetime(year, 10, 1) + relativedelta(weekday=MO(+2))), None) # Removing Columbus Day
        # Add Holiday Date(s)
        self.append({datetime.date(datetime(year, 12, 24)) : "Christmas Eve"})
        self.append({datetime.date(datetime(year, 12, 31)) : "New Years Eve"})
        self.append({datetime.date(datetime(year, 11, 1) + relativedelta(weekday=FR(+4))) : "Black Friday"}) # Adding Black Friday

Where print(self) renders a list as such:

{datetime.date(2018, 1, 1): "New Year's Day", datetime.date(2018, 1, 15): 'Martin Luther King, Jr. Day', datetime.date(2018, 2, 19): "Washington's Birthday", datetime.date(2018, 5, 28): 'Memorial Day', datetime.date(2018, 7, 4): 'Independence Day', datetime.date(2018, 9, 3): 'Labor Day', datetime.date(2018, 11, 11): 'Veterans Day', datetime.date(2018, 11, 12): 'Veterans Day (Observed)', datetime.date(2018, 11, 22): 'Thanksgiving', datetime.date(2018, 12, 25): 'Christmas Day', datetime.date(2018, 12, 24): 'Christmas Eve', datetime.date(2018, 12, 31): 'New Years Eve', datetime.date(2018, 11, 23): 'Black Friday'}....

Upvotes: 2

Views: 1840

Answers (2)

Jan von der Marwitz
Jan von der Marwitz

Reputation: 1

Since, Thanksgiving is always a Thursday AND Black Friday is always a day later, you can identify Thankgiving Day directly (via holidays package) and then just add a day:

from datetime import datetime, timedelta
import holidays

us_holidays = holidays.UnitedStates(years=2020)
black_friday = us_holidays.get_named('Thanksgiving')[0] + timedelta(days=1)

print(black_friday)

Upvotes: 0

maow
maow

Reputation: 2887

Thanksgiving is (according to Wikipedia) always the forth Thursday in November. This causes a problem for you if the month starts on a Friday. So rather than using the forth Friday try to use the forth Thursday and add a final day to make it Friday. Something like

datetime.date(datetime(year, 11, 1) + relativedelta(weekday=TH(+4)) + timedelta(days=1))

In [5]: datetime.date(datetime(2018, 11, 1) + relativedelta(weekday=TH(+4)) + timedelta(days=1))                                                                                                            
Out[5]: datetime.date(2018, 11, 23)

In [6]: datetime.date(datetime(2019, 11, 1) + relativedelta(weekday=TH(+4)) + timedelta(days=1))                                                                                                            
Out[6]: datetime.date(2019, 11, 29)

should do the trick

Upvotes: 3

Related Questions