ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
WorkDay.php
Go to the documentation of this file.
1<?php
2
4
7
8class WorkDay
9{
31 public static function date($startDate, $endDays, ...$dateArgs)
32 {
33 // Retrieve the mandatory start date and days that are referenced in the function definition
34 try {
35 $startDate = Helpers::getDateValue($startDate);
36 $endDays = Helpers::validateNumericNull($endDays);
37 $dateArgs = Functions::flattenArray($dateArgs);
38 $holidayArray = [];
39 foreach ($dateArgs as $holidayDate) {
40 $holidayArray[] = Helpers::getDateValue($holidayDate);
41 }
42 } catch (Exception $e) {
43 return $e->getMessage();
44 }
45
46 $startDate = (float) floor($startDate);
47 $endDays = (int) floor($endDays);
48 // If endDays is 0, we always return startDate
49 if ($endDays == 0) {
50 return $startDate;
51 }
52 if ($endDays < 0) {
53 return self::decrementing($startDate, $endDays, $holidayArray);
54 }
55
56 return self::incrementing($startDate, $endDays, $holidayArray);
57 }
58
64 private static function incrementing(float $startDate, int $endDays, array $holidayArray)
65 {
66 // Adjust the start date if it falls over a weekend
67
68 $startDoW = self::getWeekDay($startDate, 3);
69 if (self::getWeekDay($startDate, 3) >= 5) {
70 $startDate += 7 - $startDoW;
71 --$endDays;
72 }
73
74 // Add endDays
75 $endDate = (float) $startDate + ((int) ($endDays / 5) * 7);
76 $endDays = $endDays % 5;
77 while ($endDays > 0) {
78 ++$endDate;
79 // Adjust the calculated end date if it falls over a weekend
80 $endDow = self::getWeekDay($endDate, 3);
81 if ($endDow >= 5) {
82 $endDate += 7 - $endDow;
83 }
84 --$endDays;
85 }
86
87 // Test any extra holiday parameters
88 if (!empty($holidayArray)) {
89 $endDate = self::incrementingArray($startDate, $endDate, $holidayArray);
90 }
91
92 return Helpers::returnIn3FormatsFloat($endDate);
93 }
94
95 private static function incrementingArray(float $startDate, float $endDate, array $holidayArray): float
96 {
97 $holidayCountedArray = $holidayDates = [];
98 foreach ($holidayArray as $holidayDate) {
99 if (self::getWeekDay($holidayDate, 3) < 5) {
100 $holidayDates[] = $holidayDate;
101 }
102 }
103 sort($holidayDates, SORT_NUMERIC);
104 foreach ($holidayDates as $holidayDate) {
105 if (($holidayDate >= $startDate) && ($holidayDate <= $endDate)) {
106 if (!in_array($holidayDate, $holidayCountedArray)) {
107 ++$endDate;
108 $holidayCountedArray[] = $holidayDate;
109 }
110 }
111 // Adjust the calculated end date if it falls over a weekend
112 $endDoW = self::getWeekDay($endDate, 3);
113 if ($endDoW >= 5) {
114 $endDate += 7 - $endDoW;
115 }
116 }
117
118 return $endDate;
119 }
120
126 private static function decrementing(float $startDate, int $endDays, array $holidayArray)
127 {
128 // Adjust the start date if it falls over a weekend
129
130 $startDoW = self::getWeekDay($startDate, 3);
131 if (self::getWeekDay($startDate, 3) >= 5) {
132 $startDate += -$startDoW + 4;
133 ++$endDays;
134 }
135
136 // Add endDays
137 $endDate = (float) $startDate + ((int) ($endDays / 5) * 7);
138 $endDays = $endDays % 5;
139 while ($endDays < 0) {
140 --$endDate;
141 // Adjust the calculated end date if it falls over a weekend
142 $endDow = self::getWeekDay($endDate, 3);
143 if ($endDow >= 5) {
144 $endDate += 4 - $endDow;
145 }
146 ++$endDays;
147 }
148
149 // Test any extra holiday parameters
150 if (!empty($holidayArray)) {
151 $endDate = self::decrementingArray($startDate, $endDate, $holidayArray);
152 }
153
154 return Helpers::returnIn3FormatsFloat($endDate);
155 }
156
157 private static function decrementingArray(float $startDate, float $endDate, array $holidayArray): float
158 {
159 $holidayCountedArray = $holidayDates = [];
160 foreach ($holidayArray as $holidayDate) {
161 if (self::getWeekDay($holidayDate, 3) < 5) {
162 $holidayDates[] = $holidayDate;
163 }
164 }
165 rsort($holidayDates, SORT_NUMERIC);
166 foreach ($holidayDates as $holidayDate) {
167 if (($holidayDate <= $startDate) && ($holidayDate >= $endDate)) {
168 if (!in_array($holidayDate, $holidayCountedArray)) {
169 --$endDate;
170 $holidayCountedArray[] = $holidayDate;
171 }
172 }
173 // Adjust the calculated end date if it falls over a weekend
174 $endDoW = self::getWeekDay($endDate, 3);
175 if ($endDoW >= 5) {
176 $endDate += -$endDoW + 4;
177 }
178 }
179
180 return $endDate;
181 }
182
183 private static function getWeekDay(float $date, int $wd): int
184 {
185 $result = Week::day($date, $wd);
186
187 return is_string($result) ? -1 : $result;
188 }
189}
$result
An exception for terminatinating execution or to throw for unit testing.
static getDateValue($dateValue, bool $allowBool=true)
getDateValue.
Definition: Helpers.php:31
static validateNumericNull($number)
Many functions accept null argument treated as 0.
Definition: Helpers.php:243
static returnIn3FormatsFloat(float $excelDateValue)
Return result in one of three formats.
Definition: Helpers.php:173
static day($dateValue, $style=1)
WEEKDAY.
Definition: Week.php:131
static incrementing(float $startDate, int $endDays, array $holidayArray)
Use incrementing logic to determine Workday.
Definition: WorkDay.php:64
static decrementingArray(float $startDate, float $endDate, array $holidayArray)
Definition: WorkDay.php:157
static decrementing(float $startDate, int $endDays, array $holidayArray)
Use decrementing logic to determine Workday.
Definition: WorkDay.php:126
static incrementingArray(float $startDate, float $endDate, array $holidayArray)
Definition: WorkDay.php:95
static date($startDate, $endDays,... $dateArgs)
WORKDAY.
Definition: WorkDay.php:31
static flattenArray($array)
Convert a multi-dimensional array to a simple 1-dimensional array.
Definition: Functions.php:583