44from dateutil .relativedelta import MO , TU , WE , TH , FR , SA , SU
55from pandas .tseries .offsets import Easter , Day
66
7+
78def next_monday (dt ):
89 """
910 If holiday falls on Saturday, use following Monday instead;
@@ -116,7 +117,8 @@ class Holiday(object):
116117 for observance.
117118 """
118119 def __init__ (self , name , year = None , month = None , day = None , offset = None ,
119- observance = None , start_date = None , end_date = None ):
120+ observance = None , start_date = None , end_date = None ,
121+ days_of_week = None ):
120122 """
121123 Parameters
122124 ----------
@@ -127,6 +129,24 @@ class from pandas.tseries.offsets
127129 computes offset from date
128130 observance: function
129131 computes when holiday is given a pandas Timestamp
132+ days_of_week:
133+ provide a tuple of days e.g (0,1,2,3,) for Monday Through Thursday
134+ Monday=0,..,Sunday=6
135+
136+ Examples
137+ --------
138+ >>> from pandas.tseries.holiday import Holiday, nearest_workday
139+ >>> from pandas import DateOffset
140+ >>> from dateutil.relativedelta import MO
141+ >>> USMemorialDay = Holiday('MemorialDay', month=5, day=24,
142+ offset=DateOffset(weekday=MO(1)))
143+ >>> USLaborDay = Holiday('Labor Day', month=9, day=1,
144+ offset=DateOffset(weekday=MO(1)))
145+ >>> July3rd = Holiday('July 3rd', month=7, day=3,)
146+ >>> NewYears = Holiday('New Years Day', month=1, day=1,
147+ observance=nearest_workday),
148+ >>> July3rd = Holiday('July 3rd', month=7, day=3,
149+ days_of_week=(0, 1, 2, 3))
130150 """
131151 self .name = name
132152 self .year = year
@@ -136,6 +156,8 @@ class from pandas.tseries.offsets
136156 self .start_date = start_date
137157 self .end_date = end_date
138158 self .observance = observance
159+ assert (days_of_week is None or type (days_of_week ) == tuple )
160+ self .days_of_week = days_of_week
139161
140162 def __repr__ (self ):
141163 info = ''
@@ -183,11 +205,15 @@ def dates(self, start_date, end_date, return_name=False):
183205 year_offset = DateOffset (years = 1 )
184206 base_date = Timestamp (datetime (start_date .year , self .month , self .day ))
185207 dates = DatetimeIndex (start = base_date , end = end_date , freq = year_offset )
186- holiday_dates = list (self ._apply_rule (dates ))
187-
208+ holiday_dates = self ._apply_rule (dates )
209+ if self .days_of_week is not None :
210+ holiday_dates = list (filter (lambda x : x is not None and
211+ x .dayofweek in self .days_of_week ,
212+ holiday_dates ))
213+ else :
214+ holiday_dates = list (filter (lambda x : x is not None , holiday_dates ))
188215 if return_name :
189216 return Series (self .name , index = holiday_dates )
190-
191217 return holiday_dates
192218
193219 def _apply_rule (self , dates ):
@@ -207,14 +233,13 @@ def _apply_rule(self, dates):
207233 if self .observance is not None :
208234 return map (lambda d : self .observance (d ), dates )
209235
210- if not isinstance (self .offset , list ):
211- offsets = [self .offset ]
212- else :
213- offsets = self .offset
214-
215- for offset in offsets :
216- dates = list (map (lambda d : d + offset , dates ))
217-
236+ if self .offset is not None :
237+ if not isinstance (self .offset , list ):
238+ offsets = [self .offset ]
239+ else :
240+ offsets = self .offset
241+ for offset in offsets :
242+ dates = list (map (lambda d : d + offset , dates ))
218243 return dates
219244
220245holiday_calendars = {}
0 commit comments