Skip to content

Commit f054afb

Browse files
committed
added exclude_dates argument and test for holiday class
1 parent 2096b28 commit f054afb

File tree

2 files changed

+73
-1
lines changed

2 files changed

+73
-1
lines changed

pandas/tests/tseries/holiday/test_holiday.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,3 +353,57 @@ def test_holidays_with_timezone_specified_but_no_occurences():
353353
expected_results.index = expected_results.index.as_unit("ns")
354354

355355
tm.assert_equal(test_case, expected_results)
356+
357+
358+
def test_holiday_with_exclusion():
359+
# GH 54382
360+
start = Timestamp("2020-05-01")
361+
end = Timestamp("2025-05-31")
362+
exclude = [Timestamp("2022-05-30")] # Queen's platinum Jubilee
363+
default_uk_spring_bank_holiday: Holiday = Holiday(
364+
"UK Spring Bank Holiday",
365+
month=5,
366+
day=31,
367+
offset=DateOffset(weekday=MO(-1)),
368+
)
369+
370+
queens_jubilee_uk_spring_bank_holiday: Holiday = Holiday(
371+
"Queen's Jubilee UK Spring Bank Holiday",
372+
month=5,
373+
day=31,
374+
offset=DateOffset(weekday=MO(-1)),
375+
exclude_dates=exclude,
376+
)
377+
378+
original_dates = list(default_uk_spring_bank_holiday.dates(start, end))
379+
exclusion_dates = list(queens_jubilee_uk_spring_bank_holiday.dates(start, end))
380+
381+
assert all(ex in original_dates for ex in exclude)
382+
assert all(ex not in exclusion_dates for ex in exclude)
383+
assert set(exclusion_dates).issubset(original_dates)
384+
385+
386+
def test_holiday_with_multiple_exclusions():
387+
start = Timestamp("2000-01-01")
388+
end = Timestamp("2100-05-31")
389+
exclude = [
390+
Timestamp("2025-01-01"),
391+
Timestamp("2042-01-01"),
392+
Timestamp("2061-01-01"),
393+
] # Yakudoshi new year
394+
default_japan_new_year: Holiday = Holiday(
395+
"Japan New Year",
396+
month=1,
397+
day=1,
398+
)
399+
400+
yakudoshi_new_year: Holiday = Holiday(
401+
"Yakudoshi New Year", month=1, day=1, exclude_dates=exclude
402+
)
403+
404+
original_dates = list(default_japan_new_year.dates(start, end))
405+
exclusion_dates = list(yakudoshi_new_year.dates(start, end))
406+
407+
assert all(ex in original_dates for ex in exclude)
408+
assert all(ex not in exclusion_dates for ex in exclude)
409+
assert set(exclusion_dates).issubset(original_dates)

pandas/tseries/holiday.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
datetime,
55
timedelta,
66
)
7-
from typing import TYPE_CHECKING
7+
from typing import (
8+
TYPE_CHECKING,
9+
Any,
10+
)
811
import warnings
912

1013
from dateutil.relativedelta import (
@@ -169,6 +172,7 @@ def __init__(
169172
start_date=None,
170173
end_date=None,
171174
days_of_week: tuple | None = None,
175+
exclude_dates: list[Any] | None = None,
172176
) -> None:
173177
"""
174178
Parameters
@@ -193,6 +197,9 @@ class from pandas.tseries.offsets, default None
193197
days_of_week : tuple of int or dateutil.relativedelta weekday strs, default None
194198
Provide a tuple of days e.g (0,1,2,3,) for Monday Through Thursday
195199
Monday=0,..,Sunday=6
200+
exclude_dates : list of datetime-likes or
201+
single datetime-like, default None
202+
Specific dates to exclude e.g. skipping a specific year's holiday
196203
197204
Examples
198205
--------
@@ -257,6 +264,11 @@ class from pandas.tseries.offsets, default None
257264
self.observance = observance
258265
assert days_of_week is None or type(days_of_week) == tuple
259266
self.days_of_week = days_of_week
267+
self.exclude_dates = (
268+
[Timestamp(ex) for ex in exclude_dates]
269+
if exclude_dates is not None
270+
else exclude_dates
271+
)
260272

261273
def __repr__(self) -> str:
262274
info = ""
@@ -328,6 +340,12 @@ def dates(
328340
holiday_dates = holiday_dates[
329341
(holiday_dates >= filter_start_date) & (holiday_dates <= filter_end_date)
330342
]
343+
344+
if self.exclude_dates:
345+
holiday_dates = DatetimeIndex(
346+
[hd for hd in holiday_dates if hd not in self.exclude_dates]
347+
)
348+
331349
if return_name:
332350
return Series(self.name, index=holiday_dates)
333351
return holiday_dates

0 commit comments

Comments
 (0)