COUNT DAYS - PHP Online
Form of PHP Sandbox
Enter Your PHP code here for testing/debugging in the Online PHP Sandbox. As in the usual PHP files, you can also add HTML, but do not forget to add the tag <?php
in the places where the PHP script should be executed.
Result of php executing
Full code of COUNT DAYS.php
- <?php
- namespace App\Service;
- use App\Enum\MonthEnum;
- use DateTime;
- use DateTimeZone;
- use Exception;
- /**
- * Permet de compter le nombre de jours ouvrés pour une période donnée.
- */
- class WorkingDayCounter
- {
- /**
- * @var int
- */
- const SATURDAY_INDEX = 6;
- /**
- * @var int
- */
- const SECOND_DAY_OF_THE_MONTH = 2;
- /**
- * @var array
- */
- static $easter_dates = [
- 1990 => 640130400,
- 1991 => 670374000,
- 1992 => 703634400,
- 1993 => 734479200,
- 1994 => 765324000,
- 1995 => 797983200,
- 1996 => 828828000,
- 1997 => 859676400,
- 1998 => 892332000,
- 1999 => 923176800,
- 2000 => 956440800,
- 2001 => 987285600,
- 2002 => 1017529200,
- 2003 => 1050789600,
- 2004 => 1081634400,
- 2005 => 1111878000,
- 2006 => 1145138400,
- 2007 => 1175983200,
- 2008 => 1206226800,
- 2009 => 1239487200,
- 2010 => 1270332000,
- 2011 => 1303596000,
- 2012 => 1333836000,
- 2013 => 1364684400,
- 2014 => 1397944800,
- 2015 => 1428184800,
- 2016 => 1459033200,
- 2017 => 1492293600,
- 2018 => 1522533600,
- 2019 => 1555797600,
- 2020 => 1586642400,
- 2021 => 1617487200,
- 2022 => 1650146400,
- 2023 => 1680991200,
- 2024 => 1711839600,
- 2025 => 1745100000,
- 2026 => 1775340000,
- 2027 => 1806188400,
- 2028 => 1839448800,
- 2029 => 1869688800,
- 2030 => 1902952800,
- ];
- /**
- * Fonction permettant de compter le nombre de jours ouvrés entre deux timestamp.
- *
- * @param $startDate
- * @param $endDate
- *
- * @return int
- */
- public static function countWorkingDays($startDate, $endDate)
- {
- $holidays = []; // Tableau des jours feriés
- // On boucle dans le cas où l'année de départ serait différente de l'année d'arrivée.
- $diffYear = date('Y', $endDate) - date('Y', $startDate);
- for ($i = 0; $i <= $diffYear; $i++) {
- $year = (int)date('Y', $startDate) + $i;
- $holidays = array_merge($holidays, self::getHolidaysDaysOfAGivenYear($year));
- }
- $workingDaysCount = 0;
- // Mettre <= si on souhaite prendre en compte le dernier jour dans le décompte.
- while ($startDate < $endDate) {
- // Si le jour suivant n'est ni un dimanche (0) ou un samedi (6),
- // ni un jour férié, on incrémente les jours ouvrés.
- if (!in_array(date('w', $startDate), [0, 6])
- && !in_array(date('j_n_' . date('Y', $startDate), $startDate), $holidays)) {
- $workingDaysCount++;
- }
- $startDate = mktime(
- date('H', $startDate),
- date('i', $startDate),
- date('s', $startDate),
- date('m', $startDate),
- date('d', $startDate) + 1,
- date('Y', $startDate)
- );
- }
- return $workingDaysCount;
- }
- /**
- * @param $year
- * @return array
- */
- public static function getHolidaysDaysOfAGivenYear(int $year): array
- {
- $holidays = [];
- // Liste des jours feriés.
- $holidays[] = '1_1_' . $year; // Jour de l'an
- $holidays[] = '1_5_' . $year; // Fete du travail
- $holidays[] = '8_5_' . $year; // Victoire 1945
- $holidays[] = '14_7_' . $year; // Fête nationale
- $holidays[] = '15_8_' . $year; // Assomption
- $holidays[] = '1_11_' . $year; // Toussaint
- $holidays[] = '11_11_' . $year; // Armistice 1918
- $holidays[] = '25_12_' . $year; // Noel
- // Récupération de paques. Permet ensuite d'obtenir le jour de l'ascension et celui de la pentecote.
- $easter = self::$easter_dates[$year];
- $holidays[] = date('j_n_' . $year, $easter + 86400); // Paques
- $holidays[] = date('j_n_' . $year, $easter + (86400 * 39)); // Ascension
- $holidays[] = date('j_n_' . $year, $easter + (86400 * 50)); // Pentecote
- return $holidays;
- }
- /**
- * @param int $year
- * @param int $month
- * @return array
- */
- public static function getHolidaysDaysAsDateTimeForAGivenYearAndMonth(int $year, int $month): array
- {
- $holidays = self::getHolidaysDaysOfAGivenYear($year);
- foreach ($holidays as $k => $holiday) {
- if (!preg_match("/^(.*)_{$month}_(.*)$/", $holiday)) {
- unset($holidays[$k]);
- }
- }
- return $holidays;
- }
- /**
- * Retourne un tableau indexé par la valeur du mois avec le nombre de jours ouvrés associés à ce mois.
- *
- * @param $year
- *
- * @return array
- */
- public static function getWorkingDaysByMonth($year)
- {
- $workingDaysByMonth = [
- 'months' => [],
- 'total' => 0,
- ];
- foreach (MonthEnum::getValues() as $monthValue) {
- if ($monthValue == 12) {
- $count = WorkingDayCounter::countWorkingDays(
- strtotime($year . '-' . $monthValue . '-01'),
- strtotime(
- $year + 1 . '-01-01'
- )
- );
- $workingDaysByMonth['months'][$monthValue] = $count;
- } else {
- $count = WorkingDayCounter::countWorkingDays(
- strtotime($year . '-' . $monthValue . '-01'),
- strtotime(
- $year
- . '-'
- . MonthEnum::getValues()[array_search($monthValue, MonthEnum::getValues()) + 1]
- . '-01'
- )
- );
- $workingDaysByMonth['months'][$monthValue] = $count;
- }
- $workingDaysByMonth['total'] += $count;
- }
- return $workingDaysByMonth;
- }
- /**
- * @param int $nbOpenDaysToSubstract
- * @return DateTime
- * @throws Exception
- */
- public function getLastDayOfCurrentDateWithoutNbOpenDaysGiven(int $nbOpenDaysToSubstract): DateTime
- {
- $holidaysOfAGivenYearAndMonth = self::getHolidaysDaysAsDateTimeForAGivenYearAndMonth(date('Y'), date('n'));
- $lastDayOfMonthWithoutOpenDaysGiven = new DateTime("last day of this month", new DateTimeZone("Europe/Amsterdam"));
- while ($nbOpenDaysToSubstract > 0) {
- /// If the date isn't a sunday/saturday + no holliday => decrement
- if ($lastDayOfMonthWithoutOpenDaysGiven->format('N') < self::SATURDAY_INDEX
- && !in_array($lastDayOfMonthWithoutOpenDaysGiven->format('j_n_Y'), $holidaysOfAGivenYearAndMonth)) {
- $nbOpenDaysToSubstract--;
- }
- if($lastDayOfMonthWithoutOpenDaysGiven->format('d') < self::SECOND_DAY_OF_THE_MONTH) {
- return $lastDayOfMonthWithoutOpenDaysGiven;
- }
- $lastDayOfMonthWithoutOpenDaysGiven = $lastDayOfMonthWithoutOpenDaysGiven->modify('-1 day');
- }
- return $lastDayOfMonthWithoutOpenDaysGiven;
- }
- }
- $difference = 3;
- $service = new WorkingDayCounter();
- $resultat = $service->getLastDayOfCurrentDateWithoutNbOpenDaysGiven($difference);
- var_dump($resultat);