Files
TREK/client/src/components/Vacay/holidays.ts
T
Maurice 533d6f84d8 fix: use user locale instead of hardcoded de-DE for number/date formatting — closes #144
- CurrencyWidget: format numbers with user's locale
- ReservationModal: date formatting uses locale
- TripPDF: locale fallback to browser default instead of de-DE
- holidays.ts: formatDate accepts optional locale parameter
2026-03-30 17:28:14 +02:00

131 lines
3.8 KiB
TypeScript

const BUNDESLAENDER: Record<string, string> = {
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 easterSunday(year: number): Date {
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 new Date(year, month - 1, day)
}
function addDays(date: Date, days: number): Date {
const d = new Date(date)
d.setDate(d.getDate() + days)
return d
}
function fmt(date: Date): string {
const y = date.getFullYear()
const m = String(date.getMonth() + 1).padStart(2, '0')
const d = String(date.getDate()).padStart(2, '0')
return `${y}-${m}-${d}`
}
export function getHolidays(year: number, bundesland: string = 'NW'): Record<string, string> {
const easter = easterSunday(year)
const holidays: Record<string, string> = {}
holidays[`${year}-01-01`] = 'Neujahr'
holidays[`${year}-05-01`] = 'Tag der Arbeit'
holidays[`${year}-10-03`] = 'Tag der Deutschen Einheit'
holidays[`${year}-12-25`] = '1. Weihnachtsfeiertag'
holidays[`${year}-12-26`] = '2. Weihnachtsfeiertag'
holidays[fmt(addDays(easter, -2))] = 'Karfreitag'
holidays[fmt(addDays(easter, 1))] = 'Ostermontag'
holidays[fmt(addDays(easter, 39))] = 'Christi Himmelfahrt'
holidays[fmt(addDays(easter, 50))] = 'Pfingstmontag'
const bl = bundesland.toUpperCase()
if (['BW', 'BY', 'ST'].includes(bl)) {
holidays[`${year}-01-06`] = 'Heilige Drei Könige'
}
if (['BE', 'MV'].includes(bl)) {
holidays[`${year}-03-08`] = 'Internationaler Frauentag'
}
if (['BW', 'BY', 'HE', 'NW', 'RP', 'SL'].includes(bl)) {
holidays[fmt(addDays(easter, 60))] = 'Fronleichnam'
}
if (['SL'].includes(bl)) {
holidays[`${year}-08-15`] = 'Mariä Himmelfahrt'
}
if (bl === 'TH') {
holidays[`${year}-09-20`] = 'Weltkindertag'
}
if (['BB', 'HB', 'HH', 'MV', 'NI', 'SN', 'ST', 'SH', 'TH'].includes(bl)) {
holidays[`${year}-10-31`] = 'Reformationstag'
}
if (['BW', 'BY', 'NW', 'RP', 'SL'].includes(bl)) {
holidays[`${year}-11-01`] = 'Allerheiligen'
}
if (bl === 'SN') {
const nov23 = new Date(year, 10, 23)
const bbt = new Date(nov23)
while (bbt.getDay() !== 3) bbt.setDate(bbt.getDate() - 1)
holidays[fmt(bbt)] = 'Buß- und Bettag'
}
return holidays
}
export function isWeekend(dateStr: string, weekendDays: number[] = [0, 6]): boolean {
const d = new Date(dateStr + 'T00:00:00')
return weekendDays.includes(d.getDay())
}
export function getWeekday(dateStr: string): string {
const d = new Date(dateStr + 'T00:00:00')
return ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'][d.getDay()]
}
export function getWeekdayFull(dateStr: string): string {
const d = new Date(dateStr + 'T00:00:00')
return ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'][d.getDay()]
}
export function daysInMonth(year: number, month: number): number {
return new Date(year, month, 0).getDate()
}
export function formatDate(dateStr: string, locale?: string): string {
const d = new Date(dateStr + 'T00:00:00')
return d.toLocaleDateString(locale || undefined, { weekday: 'short', day: '2-digit', month: '2-digit', year: 'numeric' })
}
export { BUNDESLAENDER }