ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
WorkDay.php
Go to the documentation of this file.
1 <?php
2 
4 
7 
8 class 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 }
static incrementing(float $startDate, int $endDays, array $holidayArray)
Use incrementing logic to determine Workday.
Definition: WorkDay.php:64
$result
static flattenArray($array)
Convert a multi-dimensional array to a simple 1-dimensional array.
Definition: Functions.php:583
static incrementingArray(float $startDate, float $endDate, array $holidayArray)
Definition: WorkDay.php:95
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 date($startDate, $endDays,... $dateArgs)
WORKDAY.
Definition: WorkDay.php:31
static getDateValue($dateValue, bool $allowBool=true)
getDateValue.
Definition: Helpers.php:31
static decrementingArray(float $startDate, float $endDate, array $holidayArray)
Definition: WorkDay.php:157
static validateNumericNull($number)
Many functions accept null argument treated as 0.
Definition: Helpers.php:243
static decrementing(float $startDate, int $endDays, array $holidayArray)
Use decrementing logic to determine Workday.
Definition: WorkDay.php:126