diff --git a/htdocs/core/lib/date.lib.php b/htdocs/core/lib/date.lib.php index 6b688c26847e7..77fbf7944e279 100644 --- a/htdocs/core/lib/date.lib.php +++ b/htdocs/core/lib/date.lib.php @@ -1016,7 +1016,7 @@ function num_public_holiday($timestampStart, $timestampEnd, $country_code = '', /** * Return the list of public holidays including Friday, Saturday and Sunday (or not) between 2 dates in timestamp. * Dates must be UTC with hour, min, sec to 0. - * Called by function num_open_day() + * Called by function num_open_day() * * @param int $timestampStart Timestamp start (UTC with hour, min, sec = 0) * @param int $timestampEnd Timestamp end (UTC with hour, min, sec = 0) @@ -1031,263 +1031,254 @@ function num_public_holiday($timestampStart, $timestampEnd, $country_code = '', */ function list_public_holiday($timestampStart, $timestampEnd, $country_code = '', $lastday = 0, $excludesaturday = -1, $excludesunday = -1, $excludefriday = -1, $excludemonday = -1) { - global $conf, $db, $mysoc; - - // Check to ensure we use correct parameters - if (($timestampEnd - $timestampStart) % 86400 != 0) { - return 'Error Dates must use same hours and must be GMT dates'; - } - - if (empty($country_code)) { - $country_code = $mysoc->country_code; - } - if ($excludemonday < 0) { - $excludemonday = getDolGlobalInt('MAIN_NON_WORKING_DAYS_INCLUDE_MONDAY', 0); - } - if ($excludefriday < 0) { - $excludefriday = getDolGlobalInt('MAIN_NON_WORKING_DAYS_INCLUDE_FRIDAY', 0); - } - if ($excludesaturday < 0) { - $excludesaturday = getDolGlobalInt('MAIN_NON_WORKING_DAYS_INCLUDE_SATURDAY', 1); - } - if ($excludesunday < 0) { - $excludesunday = getDolGlobalInt('MAIN_NON_WORKING_DAYS_INCLUDE_SUNDAY', 1); - } - - $country_id = dol_getIdFromCode($db, $country_code, 'c_country', 'code', 'rowid'); - - if (empty($conf->cache['arrayOfActivePublicHolidays_' . $country_id])) { - // Loop on public holiday defined into hrm_public_holiday for the day, month and year analyzed - $tmpArrayOfPublicHolidays = array(); - $sql = "SELECT id, code, entity, fk_country, dayrule, year, month, day, active"; - $sql .= " FROM " . MAIN_DB_PREFIX . "c_hrm_public_holiday"; - $sql .= " WHERE active = 1 and fk_country IN (0" . ($country_id > 0 ? ", " . $country_id : 0) . ")"; - $sql .= " AND entity IN (0," . getEntity('holiday') . ")"; - - $resql = $db->query($sql); - if ($resql) { - $num_rows = $db->num_rows($resql); - $i = 0; - while ($i < $num_rows) { - $obj = $db->fetch_object($resql); - $tmpArrayOfPublicHolidays[$obj->id] = array('dayrule' => $obj->dayrule, 'year' => $obj->year, 'month' => $obj->month, 'day' => $obj->day); - $i++; - } - } else { - dol_syslog($db->lasterror(), LOG_ERR); - return 'Error sql ' . $db->lasterror(); - } - - //var_dump($tmpArrayOfPublicHolidays); - $conf->cache['arrayOfActivePublicHolidays_' . $country_id] = $tmpArrayOfPublicHolidays; - } - - $arrayOfPublicHolidays = $conf->cache['arrayOfActivePublicHolidays_' . $country_id]; - $listFeries = []; - $i = 0; - while ((($lastday == 0 && $timestampStart < $timestampEnd) || ($lastday && $timestampStart <= $timestampEnd)) - && ($i < 50000)) { // Loop end when equals (Test on i is a security loop to avoid infinite loop) - $nonWorkingDay = false; - $ferie = false; - $specialdayrule = array(); - - $jour = (int)gmdate("d", $timestampStart); - $mois = (int)gmdate("m", $timestampStart); - $annee = (int)gmdate("Y", $timestampStart); - - // If we have to exclude Friday, Saturday and Sunday - if ($excludefriday || $excludesaturday || $excludesunday) { - $jour_julien = unixtojd($timestampStart); - $jour_semaine = jddayofweek($jour_julien, 0); - if ($excludefriday) { //Friday (5), Saturday (6) and Sunday (0) - if ($jour_semaine == 5) { - $nonWorkingDay = true; - } - } - if ($excludesaturday) { //Friday (5), Saturday (6) and Sunday (0) - if ($jour_semaine == 6) { - $nonWorkingDay = true; - } - } - if ($excludesunday) { //Friday (5), Saturday (6) and Sunday (0) - if ($jour_semaine == 0) { - $nonWorkingDay = true; - } - } - } - //print "ferie=".$nonWorkingDay."\n"; - - if (!$nonWorkingDay) { - //print "jour=".$jour." month=".$mois." year=".$annee." includesaturday=".$excludesaturday." includesunday=".$excludesunday."\n"; - foreach ($arrayOfPublicHolidays as $entrypublicholiday) { - if (!empty($entrypublicholiday['dayrule']) && $entrypublicholiday['dayrule'] != 'date') { // For example 'easter', '...' - $specialdayrule[$entrypublicholiday['dayrule']] = $entrypublicholiday['dayrule']; - } else { - $match = 1; - if (!empty($entrypublicholiday['year']) && $entrypublicholiday['year'] != $annee) { - $match = 0; - } - if ($entrypublicholiday['month'] != $mois) { - $match = 0; - } - if ($entrypublicholiday['day'] != $jour) { - $match = 0; - } - - if ($match) { - $ferie = true; - $listFeries[] = $timestampStart; - } - } - - $i++; - } - //var_dump($specialdayrule)."\n"; - //print "ferie=".$nonWorkingDay."\n"; - } - - if (!$nonWorkingDay && !$ferie) { - // Special dayrules - if (in_array('easter', $specialdayrule)) { - // Calculation for easter date - $date_paques = getGMTEasterDatetime($annee); - $jour_paques = gmdate("d", $date_paques); - $mois_paques = gmdate("m", $date_paques); - if ($jour_paques == $jour && $mois_paques == $mois) { - $ferie = true; - $listFeries[] = $timestampStart; - - } - // Easter (sunday) - } - - if (in_array('eastermonday', $specialdayrule)) { - // Calculation for the monday of easter date - $date_paques = getGMTEasterDatetime($annee); - //print 'PPP'.$date_paques.' '.dol_print_date($date_paques, 'dayhour', 'gmt')." "; - $date_lundi_paques = $date_paques + (3600 * 24); - $jour_lundi_paques = gmdate("d", $date_lundi_paques); - $mois_lundi_paques = gmdate("m", $date_lundi_paques); - if ($jour_lundi_paques == $jour && $mois_lundi_paques == $mois) { - $ferie = true; - $listFeries[] = $timestampStart; - - } - // Easter (monday) - //print 'annee='.$annee.' $jour='.$jour.' $mois='.$mois.' $jour_lundi_paques='.$jour_lundi_paques.' $mois_lundi_paques='.$mois_lundi_paques."\n"; - } - - //Good Friday - if (in_array('goodfriday', $specialdayrule)) { - // Pulls the date of Easter - $easter = getGMTEasterDatetime($annee); - - // Calculates the date of Good Friday based on Easter - $date_good_friday = $easter - (2 * 3600 * 24); - $dom_good_friday = gmdate("d", $date_good_friday); - $month_good_friday = gmdate("m", $date_good_friday); - - if ($dom_good_friday == $jour && $month_good_friday == $mois) { - $ferie = true; - $listFeries[] = $timestampStart; - - } - } - - if (in_array('ascension', $specialdayrule)) { - // Calcul du jour de l'ascension (39 days after easter day) - $date_paques = getGMTEasterDatetime($annee); - $date_ascension = $date_paques + (3600 * 24 * 39); - $jour_ascension = gmdate("d", $date_ascension); - $mois_ascension = gmdate("m", $date_ascension); - if ($jour_ascension == $jour && $mois_ascension == $mois) { - $ferie = true; - $listFeries[] = $timestampStart; - - } - // Ascension (thursday) - } - - if (in_array('pentecost', $specialdayrule)) { - // Calculation of "Pentecote" (49 days after easter day) - $date_paques = getGMTEasterDatetime($annee); - $date_pentecote = $date_paques + (3600 * 24 * 49); - $jour_pentecote = gmdate("d", $date_pentecote); - $mois_pentecote = gmdate("m", $date_pentecote); - if ($jour_pentecote == $jour && $mois_pentecote == $mois) { - $ferie = true; - $listFeries[] = $timestampStart; - - } - // "Pentecote" (sunday) - } - - if (in_array('pentecotemonday', $specialdayrule)) { - // Calculation of "Pentecote" (49 days after easter day) - $date_paques = getGMTEasterDatetime($annee); - $date_pentecote = $date_paques + (3600 * 24 * 50); - $jour_pentecote = gmdate("d", $date_pentecote); - $mois_pentecote = gmdate("m", $date_pentecote); - if ($jour_pentecote == $jour && $mois_pentecote == $mois) { - $ferie = true; - $listFeries[] = $timestampStart; - - } - // "Pentecote" (monday) - } - - if (in_array('viernessanto', $specialdayrule)) { - // Viernes Santo - $date_paques = getGMTEasterDatetime($annee); - $date_viernes = $date_paques - (3600 * 24 * 2); - $jour_viernes = gmdate("d", $date_viernes); - $mois_viernes = gmdate("m", $date_viernes); - if ($jour_viernes == $jour && $mois_viernes == $mois) { - $ferie = true; - $listFeries[] = $timestampStart; - - } - //Viernes Santo - } - - if (in_array('fronleichnam', $specialdayrule)) { - // Fronleichnam (60 days after easter sunday) - $date_paques = getGMTEasterDatetime($annee); - $date_fronleichnam = $date_paques + (3600 * 24 * 60); - $jour_fronleichnam = gmdate("d", $date_fronleichnam); - $mois_fronleichnam = gmdate("m", $date_fronleichnam); - if ($jour_fronleichnam == $jour && $mois_fronleichnam == $mois) { - $ferie = true; - $listFeries[] = $timestampStart; - - } - // Fronleichnam - } - - if (in_array('genevafast', $specialdayrule)) { - // Geneva fast in Switzerland (Thursday after the first sunday in September) - $date_1sunsept = strtotime('next thursday', strtotime('next sunday', mktime(0, 0, 0, 9, 1, $annee))); - $jour_1sunsept = date("d", $date_1sunsept); - $mois_1sunsept = date("m", $date_1sunsept); - if ($jour_1sunsept == $jour && $mois_1sunsept == $mois) { - $ferie = true; - $listFeries[] = $timestampStart; - - } - // Geneva fast in Switzerland - } - } - //print "ferie=".$nonWorkingDay."\n"; - - // Increase number of days (on go up into loop) - $timestampStart = dol_time_plus_duree($timestampStart, 1, 'd'); - //var_dump($jour.' '.$mois.' '.$annee.' '.$timestampStart); - - $i++; - } - - //print "nbFerie=".$nbFerie."\n"; - return $listFeries; + global $conf, $db, $mysoc; + + // Check to ensure we use correct parameters + if (($timestampEnd - $timestampStart) % 86400 != 0) { + return 'Error Dates must use same hours and must be GMT dates'; + } + + if (empty($country_code)) { + $country_code = $mysoc->country_code; + } + if ($excludemonday < 0) { + $excludemonday = getDolGlobalInt('MAIN_NON_WORKING_DAYS_INCLUDE_MONDAY', 0); + } + if ($excludefriday < 0) { + $excludefriday = getDolGlobalInt('MAIN_NON_WORKING_DAYS_INCLUDE_FRIDAY', 0); + } + if ($excludesaturday < 0) { + $excludesaturday = getDolGlobalInt('MAIN_NON_WORKING_DAYS_INCLUDE_SATURDAY', 1); + } + if ($excludesunday < 0) { + $excludesunday = getDolGlobalInt('MAIN_NON_WORKING_DAYS_INCLUDE_SUNDAY', 1); + } + + $country_id = dol_getIdFromCode($db, $country_code, 'c_country', 'code', 'rowid'); + + if (empty($conf->cache['arrayOfActivePublicHolidays_' . $country_id])) { + // Loop on public holiday defined into hrm_public_holiday for the day, month and year analyzed + $tmpArrayOfPublicHolidays = array(); + $sql = "SELECT id, code, entity, fk_country, dayrule, year, month, day, active"; + $sql .= " FROM " . MAIN_DB_PREFIX . "c_hrm_public_holiday"; + $sql .= " WHERE active = 1 and fk_country IN (0" . ($country_id > 0 ? ", " . $country_id : 0) . ")"; + $sql .= " AND entity IN (0," . getEntity('holiday') . ")"; + + $resql = $db->query($sql); + if ($resql) { + $num_rows = $db->num_rows($resql); + $i = 0; + while ($i < $num_rows) { + $obj = $db->fetch_object($resql); + $tmpArrayOfPublicHolidays[$obj->id] = array('dayrule' => $obj->dayrule, 'year' => $obj->year, 'month' => $obj->month, 'day' => $obj->day); + $i++; + } + } else { + dol_syslog($db->lasterror(), LOG_ERR); + return 'Error sql ' . $db->lasterror(); + } + + //var_dump($tmpArrayOfPublicHolidays); + $conf->cache['arrayOfActivePublicHolidays_' . $country_id] = $tmpArrayOfPublicHolidays; + } + + $arrayOfPublicHolidays = $conf->cache['arrayOfActivePublicHolidays_' . $country_id]; + $listFeries = []; + $i = 0; + while ((($lastday == 0 && $timestampStart < $timestampEnd) || ($lastday && $timestampStart <= $timestampEnd)) + && ($i < 50000)) { // Loop end when equals (Test on i is a security loop to avoid infinite loop) + $nonWorkingDay = false; + $ferie = false; + $specialdayrule = array(); + + $jour = (int) gmdate("d", $timestampStart); + $mois = (int) gmdate("m", $timestampStart); + $annee = (int) gmdate("Y", $timestampStart); + + // If we have to exclude Friday, Saturday and Sunday + if ($excludefriday || $excludesaturday || $excludesunday) { + $jour_julien = unixtojd($timestampStart); + $jour_semaine = jddayofweek($jour_julien, 0); + if ($excludefriday) { //Friday (5), Saturday (6) and Sunday (0) + if ($jour_semaine == 5) { + $nonWorkingDay = true; + } + } + if ($excludesaturday) { //Friday (5), Saturday (6) and Sunday (0) + if ($jour_semaine == 6) { + $nonWorkingDay = true; + } + } + if ($excludesunday) { //Friday (5), Saturday (6) and Sunday (0) + if ($jour_semaine == 0) { + $nonWorkingDay = true; + } + } + } + //print "ferie=".$nonWorkingDay."\n"; + + if (!$nonWorkingDay) { + //print "jour=".$jour." month=".$mois." year=".$annee." includesaturday=".$excludesaturday." includesunday=".$excludesunday."\n"; + foreach ($arrayOfPublicHolidays as $entrypublicholiday) { + if (!empty($entrypublicholiday['dayrule']) && $entrypublicholiday['dayrule'] != 'date') { // For example 'easter', '...' + $specialdayrule[$entrypublicholiday['dayrule']] = $entrypublicholiday['dayrule']; + } else { + $match = 1; + if (!empty($entrypublicholiday['year']) && $entrypublicholiday['year'] != $annee) { + $match = 0; + } + if ($entrypublicholiday['month'] != $mois) { + $match = 0; + } + if ($entrypublicholiday['day'] != $jour) { + $match = 0; + } + + if ($match) { + $ferie = true; + $listFeries[] = $timestampStart; + } + } + + $i++; + } + //var_dump($specialdayrule)."\n"; + //print "ferie=".$nonWorkingDay."\n"; + } + + if (!$nonWorkingDay && !$ferie) { + // Special dayrules + if (in_array('easter', $specialdayrule)) { + // Calculation for easter date + $date_paques = getGMTEasterDatetime($annee); + $jour_paques = gmdate("d", $date_paques); + $mois_paques = gmdate("m", $date_paques); + if ($jour_paques == $jour && $mois_paques == $mois) { + $ferie = true; + $listFeries[] = $timestampStart; + } + // Easter (sunday) + } + + if (in_array('eastermonday', $specialdayrule)) { + // Calculation for the monday of easter date + $date_paques = getGMTEasterDatetime($annee); + //print 'PPP'.$date_paques.' '.dol_print_date($date_paques, 'dayhour', 'gmt')." "; + $date_lundi_paques = $date_paques + (3600 * 24); + $jour_lundi_paques = gmdate("d", $date_lundi_paques); + $mois_lundi_paques = gmdate("m", $date_lundi_paques); + if ($jour_lundi_paques == $jour && $mois_lundi_paques == $mois) { + $ferie = true; + $listFeries[] = $timestampStart; + } + // Easter (monday) + //print 'annee='.$annee.' $jour='.$jour.' $mois='.$mois.' $jour_lundi_paques='.$jour_lundi_paques.' $mois_lundi_paques='.$mois_lundi_paques."\n"; + } + + //Good Friday + if (in_array('goodfriday', $specialdayrule)) { + // Pulls the date of Easter + $easter = getGMTEasterDatetime($annee); + + // Calculates the date of Good Friday based on Easter + $date_good_friday = $easter - (2 * 3600 * 24); + $dom_good_friday = gmdate("d", $date_good_friday); + $month_good_friday = gmdate("m", $date_good_friday); + + if ($dom_good_friday == $jour && $month_good_friday == $mois) { + $ferie = true; + $listFeries[] = $timestampStart; + } + } + + if (in_array('ascension', $specialdayrule)) { + // Calcul du jour de l'ascension (39 days after easter day) + $date_paques = getGMTEasterDatetime($annee); + $date_ascension = $date_paques + (3600 * 24 * 39); + $jour_ascension = gmdate("d", $date_ascension); + $mois_ascension = gmdate("m", $date_ascension); + if ($jour_ascension == $jour && $mois_ascension == $mois) { + $ferie = true; + $listFeries[] = $timestampStart; + } + // Ascension (thursday) + } + + if (in_array('pentecost', $specialdayrule)) { + // Calculation of "Pentecote" (49 days after easter day) + $date_paques = getGMTEasterDatetime($annee); + $date_pentecote = $date_paques + (3600 * 24 * 49); + $jour_pentecote = gmdate("d", $date_pentecote); + $mois_pentecote = gmdate("m", $date_pentecote); + if ($jour_pentecote == $jour && $mois_pentecote == $mois) { + $ferie = true; + $listFeries[] = $timestampStart; + } + // "Pentecote" (sunday) + } + + if (in_array('pentecotemonday', $specialdayrule)) { + // Calculation of "Pentecote" (49 days after easter day) + $date_paques = getGMTEasterDatetime($annee); + $date_pentecote = $date_paques + (3600 * 24 * 50); + $jour_pentecote = gmdate("d", $date_pentecote); + $mois_pentecote = gmdate("m", $date_pentecote); + if ($jour_pentecote == $jour && $mois_pentecote == $mois) { + $ferie = true; + $listFeries[] = $timestampStart; + } + // "Pentecote" (monday) + } + + if (in_array('viernessanto', $specialdayrule)) { + // Viernes Santo + $date_paques = getGMTEasterDatetime($annee); + $date_viernes = $date_paques - (3600 * 24 * 2); + $jour_viernes = gmdate("d", $date_viernes); + $mois_viernes = gmdate("m", $date_viernes); + if ($jour_viernes == $jour && $mois_viernes == $mois) { + $ferie = true; + $listFeries[] = $timestampStart; + } + //Viernes Santo + } + + if (in_array('fronleichnam', $specialdayrule)) { + // Fronleichnam (60 days after easter sunday) + $date_paques = getGMTEasterDatetime($annee); + $date_fronleichnam = $date_paques + (3600 * 24 * 60); + $jour_fronleichnam = gmdate("d", $date_fronleichnam); + $mois_fronleichnam = gmdate("m", $date_fronleichnam); + if ($jour_fronleichnam == $jour && $mois_fronleichnam == $mois) { + $ferie = true; + $listFeries[] = $timestampStart; + } + // Fronleichnam + } + + if (in_array('genevafast', $specialdayrule)) { + // Geneva fast in Switzerland (Thursday after the first sunday in September) + $date_1sunsept = strtotime('next thursday', strtotime('next sunday', mktime(0, 0, 0, 9, 1, $annee))); + $jour_1sunsept = date("d", $date_1sunsept); + $mois_1sunsept = date("m", $date_1sunsept); + if ($jour_1sunsept == $jour && $mois_1sunsept == $mois) { + $ferie = true; + $listFeries[] = $timestampStart; + } + // Geneva fast in Switzerland + } + } + //print "ferie=".$nonWorkingDay."\n"; + + // Increase number of days (on go up into loop) + $timestampStart = dol_time_plus_duree($timestampStart, 1, 'd'); + //var_dump($jour.' '.$mois.' '.$annee.' '.$timestampStart); + + $i++; + } + + //print "nbFerie=".$nbFerie."\n"; + return $listFeries; } /**