Skip to content
Snippets Groups Projects

FeastInfo - feast day info in php/javascript / Feiertage in php/javascript

  • Clone with SSH
  • Clone with HTTPS
  • Embed
  • Share
    The snippet can be accessed without any authentication.
    Authored by Björn Bartels

    methods to calculate easter date and retrieve (german) feast days; find next/last workday respecting feast days; (php, javascript)

    functions/methods:

    • getFeastInfo,
    • findLastFeastDay,
    • findLastWorkDay,
    • findNextWorkDay,
    • isWeekend,
    • easterDate
    Edited
    FeastInfo.php 6.92 KiB
    <?php
    
    declare(strict_types=1);
    
    if (!function_exists('easter_date')) {
        /**
         * replacement for missing `easter_date` function
         * (!): Gregorian dates are fine, but only works
         *      for Julian dates between 1900-2100
         *
         * @param int $year
         *
         * @return false|int
         * @see https://stackoverflow.com/a/3589696
         */
        function easter_date(int $year): bool|int
        {
            return mktime(
                0,
                0,
                0,
                (int)floor(($b =
                     ($a = (19 * (($y = $year) % 19) + 15) % 30) +
                     (2 * ($y % 4) + 4 * $y % 7 - $a + 34) % 7 + 114
                 ) / 31),
                ($b % 31) + 14,
                $y
            );
        }
    }
    
    class FeastInfo
    {
        /**
         * determine feast-day info for given date (timestamp)
         *
         * @param $tDay int|null timestamp of day to check for feast-day info 
         * @return array(
         *  'text' => '' Text
         *  'feast' => boolean true -> feast days
         *  'arState' => '' list of regions/federal states where this feast day applies, empty = all
         * )
         *
         * list of regions/federal states
         *  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
         */
        public static function getFeastInfo(int|null $tDay)
        {
    
            $md = date('md', $tDay);
            $tEaster = easter_date((int) date('Y', $tDay));
    
            $feast = '';
            $arState = [];
    
            // feast days per region
            if ($md === '0101') {
                $feast = trans('Neujahr');
            } elseif ($md === '0501') {
                $feast = trans('Erster Mai');
            } elseif ($md === '0106') {
                $feast = trans('Heiligen Drei Könige');
                $arState = ['BW', 'BY', 'ST'];
            } elseif ($md === date('md', strtotime('-2 day', $tEaster))) {
                $feast = trans('Karfreitag');
            } elseif ($md === date('md', $tEaster)) {
                $feast = trans('Ostersonntag');
            } elseif ($md === date('md', strtotime('+1 day', $tEaster))) {
                $feast = trans('Ostermontag');
                $arState = ['SN'];
            } elseif ($md === date('md', strtotime('+39 day', $tEaster))) {
                $feast = trans('Christi Himmelfahrt');
            } elseif ($md === date('md', strtotime('+49 day', $tEaster))) {
                $feast = trans('Pfingstsonntag');
            } elseif ($md === date('md', strtotime('+50 day', $tEaster))) {
                $feast = trans('Pfingstmontag');
            } elseif ($md === date('md', strtotime('+60 day', $tEaster))) {
                $feast = trans('Fronleichnam');
                $arState = ['BW', 'BY', 'HE', 'NW', 'RP', 'SL', 'SN', 'TH'];
            } elseif ($md === '0815') {
                $feast = trans('Maria Himmelfahrt');
                $arState = ['SL', 'BY'];
            } elseif ($md === '1003') {
                $feast = trans('Tag der deutschen Einheit');
            } elseif ($md === '1031') {
                $feast = trans('Reformationstag');
                $arState = ['BB', 'MV', 'SN', 'ST', 'TH'];
            } elseif ($md === '1101') {
                $feast = trans('Allerheiligen');
                $arState = ['BW', 'BY', 'NW', 'RP', 'SL'];
            } elseif ($md === date('md', strtotime('last wednesday', mktime(0, 0, 0, 11, 23, (int) date('Y', $tDay))))) {
                $feast = trans('Buß- und Bettag');
                $arState = ['SN'];
            } elseif ($md === '1224') {
                $feast = trans('Heiliger Abend');
            } elseif ($md === '1225') {
                $feast = trans('1. Weihnachtsfeiertag');
            } elseif ($md === '1226') {
                $feast = trans('2. Weihnachtsfeiertag');
            } elseif ($md === '1231') {
                $feast = trans('Silvester (Bankfeiertag)');
            } elseif ($md === '0803') {
                $feast = trans('Internationaler Frauentag');
                $arState = ['BE'];
            }
    
            $text = '';
            if (date('N', $tDay) === '6') {
                $text = 'Samstag';
            } elseif (date('N', $tDay) === '7') {
                $text = 'Sonntag';
            }
    
            if (sizeof($arState) > 0) {
                $arStateMapping = [
                    'BW' => 'Baden-Württemberg',
                    'BB' => 'Brandenburg',
                    'BY' => 'Bayern',
                    'BE' => 'Berlin',
                    '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'
                ];
    
                foreach ($arState as $k => $v) {
                    $arState[$k] = $arStateMapping[$v];
                }
            }
    
            if ($feast === '' && $text === '') {
                $text = 'Arbeitstag';
            } elseif ($feast !== '' && $text !== '') {
                $text .= ' (' . $feast . rtrim(', ' . implode(', ', $arState), ' ,') . ')';
            } elseif ($feast !== '') {
                $text = $feast . rtrim(', ' . implode(', ', $arState), ' ,');
            }
    
            return [
                'text' => $text,
                'feast' => ($feast !== ''),
                'arState' => $arState
            ];
        }
    
        /**
         * determine next non feast-day from given date
         *
         * @param int|null $tDay
         *
         * @return int|null
         */
        public static function findNextWorkDay(int|null $tDay)
        {
            $fDay = self::getFeastInfo($tDay);
            if (($fDay['feast'] === true) || self::isWeekend($tDay)) {
                return self::findNextWorkDay($tDay + (24 * 60 * 60));
            }
            return $tDay;
        }
    
        /**
         * determine last feast-day up to given date
         *
         * @param int|null $tDay
         *
         * @return int|null
         */
        public static function findLastWorkDay(int|null $tDay)
        {
            $fDay = self::getFeastInfo($tDay);
            if (($fDay['feast'] === true) || self::isWeekend($tDay)) {
                return self::findLastWorkDay($tDay - (24 * 60 * 60));
            }
            return $tDay;
        }
    
        /**
         * determine last feast-day up to given date
         *
         * @param int|null $tDay
         *
         * @return int|null
         */
        public static function findLastFeastDay(int|null $tDay)
        {
            $fDay = self::getFeastInfo($tDay);
            if ($fDay['feast'] !== true) {
                return self::findLastFeastDay($tDay - (24 * 60 * 60));
            }
            return $tDay;
        }
    
        /**
         * determine given day is a weekend day
         *
         * @param int|null $tDay
         *
         * @return bool
         */
        public static function isWeekend(int|null $tDay)
        {
            return in_array((int) date('N', $tDay), [6, 7], true);
        }
    }
    feast-info.js 6.84 KiB
    0% Loading or .
    You are about to add 0 people to the discussion. Proceed with caution.
    Finish editing this message first!
    Please register or to comment