setTimezone($timezone)->setTime(0, 0); $end = (new DateTimeImmutable($to, new DateTimeZone('UTC')))->setTimezone($timezone)->setTime(0, 0); $years = []; $day = $start; while ($day <= $end) { $years[(int) $day->format('Y')] = true; $day = $day->add(new DateInterval('P1D')); } $holidaysByDate = []; foreach (array_keys($years) as $year) { foreach ($this->holidaysForYear((int) $year, $state, $timezone) as $date => $name) { $holidaysByDate[$date] = $name; } } $result = []; $day = $start; while ($day < $end) { $key = $day->format('Y-m-d'); $result[$key] = [ 'isSunday' => (int) $day->format('N') === 7, 'holidayName' => $holidaysByDate[$key] ?? null, ]; $day = $day->add(new DateInterval('P1D')); } return $result; } private function holidaysForYear(int $year, string $state, DateTimeZone $timezone): array { $easter = (new DateTimeImmutable('@' . (string) easter_date($year)))->setTimezone($timezone)->setTime(0, 0); $holidays = [ $this->dateKey($year, 1, 1, $timezone) => 'Neujahr', $easter->sub(new DateInterval('P2D'))->format('Y-m-d') => 'Karfreitag', $easter->add(new DateInterval('P1D'))->format('Y-m-d') => 'Ostermontag', $this->dateKey($year, 5, 1, $timezone) => 'Tag der Arbeit', $easter->add(new DateInterval('P39D'))->format('Y-m-d') => 'Christi Himmelfahrt', $easter->add(new DateInterval('P50D'))->format('Y-m-d') => 'Pfingstmontag', $this->dateKey($year, 10, 3, $timezone) => 'Tag der Deutschen Einheit', $this->dateKey($year, 12, 25, $timezone) => '1. Weihnachtstag', $this->dateKey($year, 12, 26, $timezone) => '2. Weihnachtstag', ]; if (in_array($state, self::STATES_WITH_EPIPHANY, true)) { $holidays[$this->dateKey($year, 1, 6, $timezone)] = 'Heilige Drei Koenige'; } if (in_array($state, self::STATES_WITH_WOMENS_DAY, true)) { $holidays[$this->dateKey($year, 3, 8, $timezone)] = 'Internationaler Frauentag'; } if (in_array($state, self::STATES_WITH_CORPUS_CHRISTI, true)) { $holidays[$easter->add(new DateInterval('P60D'))->format('Y-m-d')] = 'Fronleichnam'; } if (in_array($state, self::STATES_WITH_ASSUMPTION, true)) { $holidays[$this->dateKey($year, 8, 15, $timezone)] = 'Mariae Himmelfahrt'; } if (in_array($state, self::STATES_WITH_REFORMATION, true)) { $holidays[$this->dateKey($year, 10, 31, $timezone)] = 'Reformationstag'; } if (in_array($state, self::STATES_WITH_ALL_SAINTS, true)) { $holidays[$this->dateKey($year, 11, 1, $timezone)] = 'Allerheiligen'; } if (in_array($state, self::STATES_WITH_REPENTANCE, true)) { $holidays[$this->repentanceDay($year, $timezone)->format('Y-m-d')] = 'Buss- und Bettag'; } return $holidays; } private function dateKey(int $year, int $month, int $day, DateTimeZone $timezone): string { return (new DateTimeImmutable(sprintf('%04d-%02d-%02d', $year, $month, $day), $timezone))->format('Y-m-d'); } private function repentanceDay(int $year, DateTimeZone $timezone): DateTimeImmutable { $day = new DateTimeImmutable(sprintf('%04d-11-23', $year), $timezone); while ((int) $day->format('N') !== 3) { $day = $day->sub(new DateInterval('P1D')); } return $day; } }