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.



Your result can be seen below.

Result of php executing





Full code of COUNT DAYS.php

  1. <?php
  2.  
  3. namespace App\Service;
  4.  
  5. use App\Enum\MonthEnum;
  6. use DateTime;
  7. use DateTimeZone;
  8. use Exception;
  9.  
  10. /**
  11.  * Permet de compter le nombre de jours ouvrés pour une période donnée.
  12.  */
  13. class WorkingDayCounter
  14. {
  15.     /**
  16.      * @var int
  17.      */
  18.     const SATURDAY_INDEX = 6;
  19.  
  20.     /**
  21.      * @var int
  22.      */
  23.     const SECOND_DAY_OF_THE_MONTH = 2;
  24.  
  25.     /**
  26.      * @var array
  27.      */
  28.     static $easter_dates = [
  29.         1990 => 640130400,
  30.         1991 => 670374000,
  31.         1992 => 703634400,
  32.         1993 => 734479200,
  33.         1994 => 765324000,
  34.         1995 => 797983200,
  35.         1996 => 828828000,
  36.         1997 => 859676400,
  37.         1998 => 892332000,
  38.         1999 => 923176800,
  39.         2000 => 956440800,
  40.         2001 => 987285600,
  41.         2002 => 1017529200,
  42.         2003 => 1050789600,
  43.         2004 => 1081634400,
  44.         2005 => 1111878000,
  45.         2006 => 1145138400,
  46.         2007 => 1175983200,
  47.         2008 => 1206226800,
  48.         2009 => 1239487200,
  49.         2010 => 1270332000,
  50.         2011 => 1303596000,
  51.         2012 => 1333836000,
  52.         2013 => 1364684400,
  53.         2014 => 1397944800,
  54.         2015 => 1428184800,
  55.         2016 => 1459033200,
  56.         2017 => 1492293600,
  57.         2018 => 1522533600,
  58.         2019 => 1555797600,
  59.         2020 => 1586642400,
  60.         2021 => 1617487200,
  61.         2022 => 1650146400,
  62.         2023 => 1680991200,
  63.         2024 => 1711839600,
  64.         2025 => 1745100000,
  65.         2026 => 1775340000,
  66.         2027 => 1806188400,
  67.         2028 => 1839448800,
  68.         2029 => 1869688800,
  69.         2030 => 1902952800,
  70.     ];
  71.  
  72.     /**
  73.      * Fonction permettant de compter le nombre de jours ouvrés entre deux timestamp.
  74.      *
  75.      * @param $startDate
  76.      * @param $endDate
  77.      *
  78.      * @return int
  79.      */
  80.     public static function countWorkingDays($startDate, $endDate)
  81.     {
  82.         $holidays = []; // Tableau des jours feriés
  83.  
  84.         // On boucle dans le cas où l'année de départ serait différente de l'année d'arrivée.
  85.         $diffYear = date('Y', $endDate) - date('Y', $startDate);
  86.  
  87.         for ($i = 0; $i <= $diffYear; $i++) {
  88.             $year = (int)date('Y', $startDate) + $i;
  89.             $holidays = array_merge($holidays, self::getHolidaysDaysOfAGivenYear($year));
  90.         }
  91.  
  92.         $workingDaysCount = 0;
  93.  
  94.         // Mettre <= si on souhaite prendre en compte le dernier jour dans le décompte.
  95.         while ($startDate < $endDate) {
  96.             // Si le jour suivant n'est ni un dimanche (0) ou un samedi (6),
  97.             // ni un jour férié, on incrémente les jours ouvrés.
  98.             if (!in_array(date('w', $startDate), [0, 6])
  99.                 && !in_array(date('j_n_' . date('Y', $startDate), $startDate), $holidays)) {
  100.                 $workingDaysCount++;
  101.             }
  102.  
  103.             $startDate = mktime(
  104.                 date('H', $startDate),
  105.                 date('i', $startDate),
  106.                 date('s', $startDate),
  107.                 date('m', $startDate),
  108.                 date('d', $startDate) + 1,
  109.                 date('Y', $startDate)
  110.             );
  111.         }
  112.  
  113.         return $workingDaysCount;
  114.     }
  115.  
  116.     /**
  117.      * @param $year
  118.      * @return array
  119.      */
  120.     public static function getHolidaysDaysOfAGivenYear(int $year): array
  121.     {
  122.         $holidays = [];
  123.  
  124.         // Liste des jours feriés.
  125.         $holidays[] = '1_1_' . $year; // Jour de l'an
  126.         $holidays[] = '1_5_' . $year; // Fete du travail
  127.         $holidays[] = '8_5_' . $year; // Victoire 1945
  128.         $holidays[] = '14_7_' . $year; // Fête nationale
  129.         $holidays[] = '15_8_' . $year; // Assomption
  130.         $holidays[] = '1_11_' . $year; // Toussaint
  131.         $holidays[] = '11_11_' . $year; // Armistice 1918
  132.         $holidays[] = '25_12_' . $year; // Noel
  133.  
  134.         // Récupération de paques. Permet ensuite d'obtenir le jour de l'ascension et celui de la pentecote.
  135.         $easter = self::$easter_dates[$year];
  136.         $holidays[] = date('j_n_' . $year, $easter + 86400); // Paques
  137.         $holidays[] = date('j_n_' . $year, $easter + (86400 * 39)); // Ascension
  138.         $holidays[] = date('j_n_' . $year, $easter + (86400 * 50)); // Pentecote
  139.  
  140.         return $holidays;
  141.     }
  142.  
  143.     /**
  144.      * @param int $year
  145.      * @param int $month
  146.      * @return array
  147.      */
  148.     public static function getHolidaysDaysAsDateTimeForAGivenYearAndMonth(int $year, int $month): array
  149.     {
  150.         $holidays = self::getHolidaysDaysOfAGivenYear($year);
  151.         foreach ($holidays as $k => $holiday) {
  152.             if (!preg_match("/^(.*)_{$month}_(.*)$/", $holiday)) {
  153.                 unset($holidays[$k]);
  154.             }
  155.         }
  156.  
  157.         return $holidays;
  158.     }
  159.  
  160.     /**
  161.      * Retourne un tableau indexé par la valeur du mois avec le nombre de jours ouvrés associés à ce mois.
  162.      *
  163.      * @param $year
  164.      *
  165.      * @return array
  166.      */
  167.     public static function getWorkingDaysByMonth($year)
  168.     {
  169.         $workingDaysByMonth = [
  170.             'months' => [],
  171.             'total' => 0,
  172.         ];
  173.  
  174.         foreach (MonthEnum::getValues() as $monthValue) {
  175.             if ($monthValue == 12) {
  176.                 $count = WorkingDayCounter::countWorkingDays(
  177.                     strtotime($year . '-' . $monthValue . '-01'),
  178.                     strtotime(
  179.                         $year + 1 . '-01-01'
  180.                     )
  181.                 );
  182.  
  183.                 $workingDaysByMonth['months'][$monthValue] = $count;
  184.             } else {
  185.                 $count = WorkingDayCounter::countWorkingDays(
  186.                     strtotime($year . '-' . $monthValue . '-01'),
  187.                     strtotime(
  188.                         $year
  189.                         . '-'
  190.                         . MonthEnum::getValues()[array_search($monthValue, MonthEnum::getValues()) + 1]
  191.                         . '-01'
  192.                     )
  193.                 );
  194.  
  195.                 $workingDaysByMonth['months'][$monthValue] = $count;
  196.             }
  197.  
  198.             $workingDaysByMonth['total'] += $count;
  199.         }
  200.  
  201.         return $workingDaysByMonth;
  202.     }
  203.  
  204.     /**
  205.      * @param int $nbOpenDaysToSubstract
  206.      * @return DateTime
  207.      * @throws Exception
  208.      */
  209.     public function getLastDayOfCurrentDateWithoutNbOpenDaysGiven(int $nbOpenDaysToSubstract): DateTime
  210.     {
  211.  
  212.         $holidaysOfAGivenYearAndMonth = self::getHolidaysDaysAsDateTimeForAGivenYearAndMonth(date('Y'), date('n'));
  213.         $lastDayOfMonthWithoutOpenDaysGiven = new DateTime("last day of this month", new DateTimeZone("Europe/Amsterdam"));
  214.  
  215.         while ($nbOpenDaysToSubstract > 0) {
  216.             /// If the date isn't a sunday/saturday + no holliday => decrement
  217.             if ($lastDayOfMonthWithoutOpenDaysGiven->format('N') < self::SATURDAY_INDEX
  218.                 && !in_array($lastDayOfMonthWithoutOpenDaysGiven->format('j_n_Y'), $holidaysOfAGivenYearAndMonth)) {
  219.                 $nbOpenDaysToSubstract--;
  220.             }
  221.  
  222.             if($lastDayOfMonthWithoutOpenDaysGiven->format('d') < self::SECOND_DAY_OF_THE_MONTH) {
  223.                 return $lastDayOfMonthWithoutOpenDaysGiven;
  224.             }
  225.  
  226.             $lastDayOfMonthWithoutOpenDaysGiven = $lastDayOfMonthWithoutOpenDaysGiven->modify('-1 day');
  227.         }
  228.  
  229.         return $lastDayOfMonthWithoutOpenDaysGiven;
  230.     }
  231. }
  232.  
  233. $difference = 3;
  234. $service = new WorkingDayCounter();
  235. $resultat = $service->getLastDayOfCurrentDateWithoutNbOpenDaysGiven($difference);
  236.  
  237. var_dump($resultat);
File Description
  • COUNT DAYS
  • PHP Code
  • 13 Jan-2020
  • 7.37 Kb
You can Share it: