// Bundesweite gesetzliche Feiertage in Deutschland. Diese 9 gelten in ALLEN // Bundesländern — sie als Nicht-Werktag zu behandeln ist daher immer korrekt. // Landesspezifische Feiertage (z. B. Fronleichnam, Reformationstag) sind hier // bewusst NICHT enthalten; die können bei Bedarf pro Bundesland ergänzt werden. const cache = new Map>(); function isoFromParts(year: number, month: number, day: number): string { return new Date(Date.UTC(year, month - 1, day)).toISOString().slice(0, 10); } function addDays(year: number, month: number, day: number, offset: number): string { const d = new Date(Date.UTC(year, month - 1, day)); d.setUTCDate(d.getUTCDate() + offset); return d.toISOString().slice(0, 10); } // Ostersonntag (gregorianisch) nach Meeus/Jones/Butcher. function easterSunday(year: number): { month: number; day: number } { const a = year % 19; const b = Math.floor(year / 100); const c = year % 100; const d = Math.floor(b / 4); const e = b % 4; const f = Math.floor((b + 8) / 25); const g = Math.floor((b - f + 1) / 3); const h = (19 * a + b - d - g + 15) % 30; const i = Math.floor(c / 4); const k = c % 4; const l = (32 + 2 * e + 2 * i - h - k) % 7; const m = Math.floor((a + 11 * h + 22 * l) / 451); const month = Math.floor((h + l - 7 * m + 114) / 31); // 3 = März, 4 = April const day = ((h + l - 7 * m + 114) % 31) + 1; return { month, day }; } export function germanNationwideHolidays(year: number): Set { const cached = cache.get(year); if (cached) return cached; const e = easterSunday(year); const set = new Set([ isoFromParts(year, 1, 1), // Neujahr addDays(year, e.month, e.day, -2), // Karfreitag addDays(year, e.month, e.day, 1), // Ostermontag isoFromParts(year, 5, 1), // Tag der Arbeit addDays(year, e.month, e.day, 39), // Christi Himmelfahrt addDays(year, e.month, e.day, 50), // Pfingstmontag isoFromParts(year, 10, 3), // Tag der Deutschen Einheit isoFromParts(year, 12, 25), // 1. Weihnachtstag isoFromParts(year, 12, 26), // 2. Weihnachtstag ]); cache.set(year, set); return set; } export function isGermanHoliday(iso: string): boolean { const year = Number(iso.slice(0, 4)); if (!Number.isFinite(year)) return false; return germanNationwideHolidays(year).has(iso); }