import { addDays } from './scheduler.js'; const pad = (n) => String(n).padStart(2, '0'); const iso = (y, m, d) => `${y}-${pad(m)}-${pad(d)}`; /** Ostersonntag nach der Gauß'schen Osterformel (Meeus/Jones/Butcher). */ export function easterSunday(year) { 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); const day = ((h + l - 7 * m + 114) % 31) + 1; return iso(year, month, day); } export const BUNDESLAENDER = { '': 'Nur bundesweite Feiertage', BW: 'Baden-Württemberg', BY: 'Bayern', BE: 'Berlin', BB: 'Brandenburg', HB: 'Bremen', HH: 'Hamburg', HE: 'Hessen', MV: 'Mecklenburg-Vorpommern', NI: 'Niedersachsen', NW: 'Nordrhein-Westfalen', RP: 'Rheinland-Pfalz', SL: 'Saarland', SN: 'Sachsen', ST: 'Sachsen-Anhalt', SH: 'Schleswig-Holstein', TH: 'Thüringen', }; function bussUndBettag(year) { // Mittwoch vor dem 23. November let d = iso(year, 11, 22); while (new Date(d + 'T00:00:00Z').getUTCDay() !== 3) d = addDays(d, -1); return d; } /** Gesetzliche Feiertage eines Jahres, bundesweit plus die des gewählten Bundeslands. */ export function germanHolidays(year, state = '') { const easter = easterSunday(year); const all = [ { date: iso(year, 1, 1), name: 'Neujahr' }, { date: iso(year, 1, 6), name: 'Heilige Drei Könige', states: ['BW', 'BY', 'ST'] }, { date: iso(year, 3, 8), name: 'Internationaler Frauentag', states: ['BE', 'MV'] }, { date: addDays(easter, -2), name: 'Karfreitag' }, { date: addDays(easter, 1), name: 'Ostermontag' }, { date: iso(year, 5, 1), name: 'Tag der Arbeit' }, { date: addDays(easter, 39), name: 'Christi Himmelfahrt' }, { date: addDays(easter, 50), name: 'Pfingstmontag' }, { date: addDays(easter, 60), name: 'Fronleichnam', states: ['BW', 'BY', 'HE', 'NW', 'RP', 'SL'] }, { date: iso(year, 8, 15), name: 'Mariä Himmelfahrt', states: ['SL', 'BY'] }, { date: iso(year, 9, 20), name: 'Weltkindertag', states: ['TH'] }, { date: iso(year, 10, 3), name: 'Tag der Deutschen Einheit' }, { date: iso(year, 10, 31), name: 'Reformationstag', states: ['BB', 'HB', 'HH', 'MV', 'NI', 'SN', 'ST', 'SH', 'TH'] }, { date: iso(year, 11, 1), name: 'Allerheiligen', states: ['BW', 'BY', 'NW', 'RP', 'SL'] }, { date: bussUndBettag(year), name: 'Buß- und Bettag', states: ['SN'] }, { date: iso(year, 12, 25), name: '1. Weihnachtstag' }, { date: iso(year, 12, 26), name: '2. Weihnachtstag' }, ]; return all .filter((h) => !h.states || h.states.includes(state)) .map(({ date, name }) => ({ date, name, auto: true })) .sort((a, b) => a.date.localeCompare(b.date)); }