Functional Weave
Code in Rust

dates.bank-holidays@1.0.1

impl/python.py

1,665 bytes · the Python implementation · view raw

Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.

from typing import List, Optional

from .dates_bank_holidays_data import BANK_HOLIDAYS  ← this capability’s own data, compiled from data/bank-holidays.json into the same file by fune build
from .dates_bank_holidays_types import BankHoliday, UkRegion


def bank_holidays(region: UkRegion, year: int) -> List[BankHoliday]:
    """The bank holidays for a UK region and year, in date order, as gov.uk
    publishes them.

    A year the data does not cover is an error rather than an empty list,
    because an empty list reads as "no holidays" and a deadline calculation
    would then count Christmas Day as a working day.
    """
    if isinstance(year, bool) or not isinstance(year, int):
        raise TypeError("year must be an integer, received %r" % (year,))
    first: Optional[int] = None
    last: Optional[int] = None
    found: List[BankHoliday] = []
    prefix = "%04d-" % (year,)
    for row in BANK_HOLIDAYS:
        if row.region != region:
            continue
        row_year = int(row.date[0:4])
        if first is None or row_year < first:
            first = row_year
        if last is None or row_year > last:
            last = row_year
        if row.date.startswith(prefix):
            found.append(BankHoliday(date=row.date, title=row.title, substitute=row.substitute))
    if first is None or last is None:
        raise ValueError(
            'unknown region "%s": expected england-and-wales, scotland or northern-ireland' % (region,)
        )
    if year < first or year > last:
        raise ValueError(
            "no bank holiday data for %s in %s: the published calendar covers %s to %s" % (region, year, first, last)
        )
    # ISO dates sort correctly as strings.
    return sorted(found, key=lambda holiday: holiday.date)