diff --git a/pendulum/date.py b/pendulum/date.py index f11164ee..8ed7707e 100644 --- a/pendulum/date.py +++ b/pendulum/date.py @@ -26,7 +26,6 @@ class Date(FormattableMixin, date): - # Names of days of the week _days = { SUNDAY: "Sunday", @@ -217,6 +216,33 @@ def is_anniversary(self, dt=None): # the old name can be completely replaced with the new in one of the future versions is_birthday = is_anniversary + def is_business_day(self, holidays: [list, tuple] = None) -> bool: + """ + Check if the date is a business day (not a weekend), including checking against an optional list of holidays + + :param holidays: list or tuple containing Date or DateTime objects to be considered holidays + :type holidays: list, tuple + + :rtype: bool + True if the date is a business day, otherwise false + """ + + # check if this date is a weekend + if self.day_of_week == SATURDAY \ + or self.day_of_week == SUNDAY: + return False + + # check if this date falls on a holiday + if holidays is not None: + # TODO: prefilter the holiday list by year (test for speed) + for holiday in holidays: + if self.is_same_day(holiday): + return False + + return False + + return True + # ADDITIONS AND SUBSTRACTIONS def add(self, years=0, months=0, weeks=0, days=0): diff --git a/tests/date/test_comparison.py b/tests/date/test_comparison.py index 052ae2f3..a81f44bf 100644 --- a/tests/date/test_comparison.py +++ b/tests/date/test_comparison.py @@ -243,3 +243,14 @@ def test_comparison_to_unsupported(): assert not dt1 == "test" assert dt1 not in ["test"] + + +def test_is_business_day(): + dt1 = pendulum.Date(2021, 11, 13) # weekend + dt2 = pendulum.Date(2021, 11, 15) # not weekend + + holidays = [pendulum.Date(2020, 11, 15)] + + assert not dt1.is_business_day() + assert dt2.is_business_day() + assert not dt2.is_business_day(holidays=holidays)