63 lines
1.9 KiB
Python
63 lines
1.9 KiB
Python
"""UK holidays."""
|
|
|
|
import json
|
|
import os
|
|
from datetime import date, datetime, timedelta
|
|
|
|
import httpx
|
|
from dateutil.easter import easter
|
|
|
|
from .types import Holiday, StrDict
|
|
|
|
url = "https://www.gov.uk/bank-holidays.json"
|
|
|
|
|
|
def json_filename(data_dir: str) -> str:
|
|
"""Filename for cached bank holidays."""
|
|
assert os.path.exists(data_dir)
|
|
return os.path.join(data_dir, "bank-holidays.json")
|
|
|
|
|
|
async def get_holiday_list(data_dir: str) -> list[StrDict]:
|
|
"""Download holiday list and save cache."""
|
|
filename = json_filename(data_dir)
|
|
|
|
async with httpx.AsyncClient() as client:
|
|
r = await client.get(url)
|
|
events: list[StrDict] = r.json()["england-and-wales"]["events"] # check valid
|
|
open(filename, "w").write(r.text)
|
|
return events
|
|
|
|
|
|
def bank_holiday_list(start_date: date, end_date: date, data_dir: str) -> list[Holiday]:
|
|
"""Date and name of the next UK bank holiday."""
|
|
filename = json_filename(data_dir)
|
|
|
|
hols: list[Holiday] = []
|
|
for event in json.load(open(filename))["england-and-wales"]["events"]:
|
|
event_date = datetime.strptime(event["date"], "%Y-%m-%d").date()
|
|
if event_date < start_date:
|
|
continue
|
|
if event_date > end_date:
|
|
break
|
|
hols.append(Holiday(date=event_date, name=event["title"], country="gb"))
|
|
|
|
return hols
|
|
|
|
|
|
def get_mothers_day(input_date: date) -> date:
|
|
"""Calculate the date of the next UK Mother's Day from the current date."""
|
|
current_year = input_date.year
|
|
easter_date = easter(current_year)
|
|
|
|
# Calculate the date of Mother's Day, which is the fourth Sunday of Lent
|
|
mothers_day = easter_date + timedelta(weeks=3)
|
|
|
|
# Check if Mother's Day has already passed this year
|
|
if input_date > mothers_day:
|
|
# If it has passed, calculate for the next year
|
|
easter_date = easter(current_year + 1)
|
|
mothers_day = easter_date + timedelta(weeks=3)
|
|
|
|
return mothers_day
|