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 Dict, Sequence, Set
from .dates_add_days import add_days, parse_iso_date ← from dates.add-days ^1.0.0 · built alongside by fune
from .dates_bank_holidays import bank_holidays ← from dates.bank-holidays ^1.0.0 · built alongside by fune
from .dates_day_of_week import day_of_week ← from dates.day-of-week ^1.0.0 · built alongside by fune
from .legal_court_deadline_types import CourtDeadline, DeadlineRule
def court_deadline(
trigger_date: str,
days: int,
rule: DeadlineRule,
at_court_office: bool,
court_closed_days: Sequence[str],
) -> CourtDeadline:
"""A deadline in days by CPR 2.8: clear days, short periods, court-office closures."""
parse_iso_date(trigger_date)
if isinstance(days, bool) or not isinstance(days, int) or days < 1:
raise ValueError("days must be an integer of at least 1, received %s" % (days,))
if rule not in ("within", "at-least-after", "at-least-before"):
raise ValueError('unknown deadline rule "%s": expected within, at-least-after or at-least-before' % (rule,))
if at_court_office and rule != "within":
raise ValueError("atCourtOffice applies only to a within period (CPR 2.8(5))")
if not at_court_office and len(court_closed_days) > 0:
raise ValueError("courtClosedDays only apply when atCourtOffice is true")
for d in court_closed_days:
parse_iso_date(d)
# England and Wales holidays by year, fetched only for the years a count touches.
holidays: Dict[int, Set[str]] = {}
def is_holiday(iso: str) -> bool:
year = int(iso[0:4])
if year not in holidays:
holidays[year] = {h.date for h in bank_holidays("england-and-wales", year)}
return iso in holidays[year]
def is_non_working(iso: str) -> bool:
return day_of_week(iso) >= 6 or is_holiday(iso)
short_period = days <= 5
step = -1 if rule == "at-least-before" else 1
# Walk the clear days: the trigger day is never one, and in a short period
# weekends and bank holidays are passed over without counting.
cursor = trigger_date
counted = 0
while counted < days:
cursor = add_days(cursor, step)
if not short_period or not is_non_working(cursor):
counted += 1
if rule != "within":
# The act or event falls on the day beyond the last clear day.
return CourtDeadline(date=add_days(cursor, step), short_period=short_period, extended=False)
date = cursor
extended = False
if at_court_office:
while is_non_working(date) or date in court_closed_days:
date = add_days(date, 1)
extended = True
return CourtDeadline(date=date, short_period=short_period, extended=extended)