Skip to content

Add substitute/observed bank holidays for Ireland (IE) #3255

@visakhr90-stack

Description

@visakhr90-stack

Description

The Ireland calendar (holidays.IE / holidays.Ireland) does not include substitute bank holidays when fixed-date public holidays fall on weekends. Irish banks observe the following Monday as a substitute holiday in these cases.

Current Behavior

import holidays
from datetime import date

cal = holidays.IE(years=2020)

# St. Stephen's Day 2020 falls on Saturday (Dec 26)
print(date(2020, 12, 26) in cal)  # True
print(date(2020, 12, 28) in cal)  # False - but should be True (substitute Monday)

Expected Behavior

When fixed-date Irish public holidays fall on weekends, the following Monday should be included as an observed/substitute holiday:

  • New Year's Day (Jan 1)
  • St. Patrick's Day (Mar 17)
  • Christmas Day (Dec 25)
  • St. Stephen's Day (Dec 26)

This is consistent with how holidays.UK handles substitute bank holidays.

Real-World Examples

Holiday Actual Date Day Substitute Date
St. Stephen's Day 2020 Dec 26, 2020 Saturday Dec 28, 2020 (Monday)
Christmas 2021 Dec 25, 2021 Saturday Dec 27, 2021 (Monday)
St. Patrick's Day 2019 Mar 17, 2019 Sunday Mar 18, 2019 (Monday)
New Year's Day 2022 Jan 1, 2022 Saturday Jan 3, 2022 (Monday)

Edge Case: Both Christmas and St. Stephen's on Weekend (2021)

When both holidays fall on a weekend (Dec 25 = Saturday, Dec 26 = Sunday), two substitute days are needed:

  • Dec 27 (Monday) = Christmas Observed
  • Dec 28 (Tuesday) = St. Stephen's Observed

Reference

Irish bank holiday rules are governed by the Organisation of Working Time Act 1997. When a public holiday falls on a weekend, the substitute day is typically the next working day (Monday).

Use Case

This is important for financial calculations (loan interest, lease payments, derivatives) where business day adjustments are required.

Workaround

from datetime import date, timedelta
from holidays.countries import Ireland

class FinancialIreland(Ireland):
    def _populate(self, year):
        super()._populate(year)
        self._add_observed(date(year, 1, 1))
        self._add_observed(date(year, 3, 17))
        self._add_observed(date(year, 12, 25))
        self._add_observed(date(year, 12, 26))

    def _add_observed(self, dt: date) -> None:
        if dt not in self:
            return
        holiday_name = self[dt]
        if dt.weekday() == 5:  # Saturday -> Monday
            target = dt + timedelta(days=2)
        elif dt.weekday() == 6:  # Sunday -> Monday
            target = dt + timedelta(days=1)
        else:
            return
        # Handle collision when both Christmas and St. Stephen's on weekend
        if target in self and "(Observed)" in self.get(target, ""):
            target = target + timedelta(days=1)
        self[target] = f"{holiday_name} (Observed)"

Environment

  • holidays version: 0.90
  • Python version: 3.10+

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions