ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Difference.php
Go to the documentation of this file.
1 <?php
2 
4 
5 use DateInterval;
6 use DateTime;
10 
12 {
24  public static function interval($startDate, $endDate, $unit = 'D')
25  {
26  try {
27  $startDate = Helpers::getDateValue($startDate);
28  $endDate = Helpers::getDateValue($endDate);
29  $difference = self::initialDiff($startDate, $endDate);
30  $unit = strtoupper(Functions::flattenSingleValue($unit));
31  } catch (Exception $e) {
32  return $e->getMessage();
33  }
34 
35  // Execute function
36  $PHPStartDateObject = SharedDateHelper::excelToDateTimeObject($startDate);
37  $startDays = (int) $PHPStartDateObject->format('j');
38  $startMonths = (int) $PHPStartDateObject->format('n');
39  $startYears = (int) $PHPStartDateObject->format('Y');
40 
41  $PHPEndDateObject = SharedDateHelper::excelToDateTimeObject($endDate);
42  $endDays = (int) $PHPEndDateObject->format('j');
43  $endMonths = (int) $PHPEndDateObject->format('n');
44  $endYears = (int) $PHPEndDateObject->format('Y');
45 
46  $PHPDiffDateObject = $PHPEndDateObject->diff($PHPStartDateObject);
47 
48  $retVal = false;
49  $retVal = self::replaceRetValue($retVal, $unit, 'D') ?? self::datedifD($difference);
50  $retVal = self::replaceRetValue($retVal, $unit, 'M') ?? self::datedifM($PHPDiffDateObject);
51  $retVal = self::replaceRetValue($retVal, $unit, 'MD') ?? self::datedifMD($startDays, $endDays, $PHPEndDateObject, $PHPDiffDateObject);
52  $retVal = self::replaceRetValue($retVal, $unit, 'Y') ?? self::datedifY($PHPDiffDateObject);
53  $retVal = self::replaceRetValue($retVal, $unit, 'YD') ?? self::datedifYD($difference, $startYears, $endYears, $PHPStartDateObject, $PHPEndDateObject);
54  $retVal = self::replaceRetValue($retVal, $unit, 'YM') ?? self::datedifYM($PHPDiffDateObject);
55 
56  return is_bool($retVal) ? Functions::VALUE() : $retVal;
57  }
58 
59  private static function initialDiff(float $startDate, float $endDate): float
60  {
61  // Validate parameters
62  if ($startDate > $endDate) {
63  throw new Exception(Functions::NAN());
64  }
65 
66  return $endDate - $startDate;
67  }
68 
76  private static function replaceRetValue($retVal, string $unit, string $compare)
77  {
78  if ($retVal !== false || $unit !== $compare) {
79  return $retVal;
80  }
81 
82  return null;
83  }
84 
85  private static function datedifD(float $difference): int
86  {
87  return (int) $difference;
88  }
89 
90  private static function datedifM(DateInterval $PHPDiffDateObject): int
91  {
92  return 12 * (int) $PHPDiffDateObject->format('%y') + (int) $PHPDiffDateObject->format('%m');
93  }
94 
95  private static function datedifMD(int $startDays, int $endDays, DateTime $PHPEndDateObject, DateInterval $PHPDiffDateObject): int
96  {
97  if ($endDays < $startDays) {
98  $retVal = $endDays;
99  $PHPEndDateObject->modify('-' . $endDays . ' days');
100  $adjustDays = (int) $PHPEndDateObject->format('j');
101  $retVal += ($adjustDays - $startDays);
102  } else {
103  $retVal = (int) $PHPDiffDateObject->format('%d');
104  }
105 
106  return $retVal;
107  }
108 
109  private static function datedifY(DateInterval $PHPDiffDateObject): int
110  {
111  return (int) $PHPDiffDateObject->format('%y');
112  }
113 
114  private static function datedifYD(float $difference, int $startYears, int $endYears, DateTime $PHPStartDateObject, DateTime $PHPEndDateObject): int
115  {
116  $retVal = (int) $difference;
117  if ($endYears > $startYears) {
118  $isLeapStartYear = $PHPStartDateObject->format('L');
119  $wasLeapEndYear = $PHPEndDateObject->format('L');
120 
121  // Adjust end year to be as close as possible as start year
122  while ($PHPEndDateObject >= $PHPStartDateObject) {
123  $PHPEndDateObject->modify('-1 year');
124  $endYears = $PHPEndDateObject->format('Y');
125  }
126  $PHPEndDateObject->modify('+1 year');
127 
128  // Get the result
129  $retVal = $PHPEndDateObject->diff($PHPStartDateObject)->days;
130 
131  // Adjust for leap years cases
132  $isLeapEndYear = $PHPEndDateObject->format('L');
133  $limit = new DateTime($PHPEndDateObject->format('Y-02-29'));
134  if (!$isLeapStartYear && !$wasLeapEndYear && $isLeapEndYear && $PHPEndDateObject >= $limit) {
135  --$retVal;
136  }
137  }
138 
139  return (int) $retVal;
140  }
141 
142  private static function datedifYM(DateInterval $PHPDiffDateObject): int
143  {
144  return (int) $PHPDiffDateObject->format('%m');
145  }
146 }
static datedifY(DateInterval $PHPDiffDateObject)
Definition: Difference.php:109
static interval($startDate, $endDate, $unit='D')
DATEDIF.
Definition: Difference.php:24
static datedifYD(float $difference, int $startYears, int $endYears, DateTime $PHPStartDateObject, DateTime $PHPEndDateObject)
Definition: Difference.php:114
static replaceRetValue($retVal, string $unit, string $compare)
Decide whether it&#39;s time to set retVal.
Definition: Difference.php:76
static datedifYM(DateInterval $PHPDiffDateObject)
Definition: Difference.php:142
static datedifM(DateInterval $PHPDiffDateObject)
Definition: Difference.php:90
static datedifMD(int $startDays, int $endDays, DateTime $PHPEndDateObject, DateInterval $PHPDiffDateObject)
Definition: Difference.php:95
static getDateValue($dateValue, bool $allowBool=true)
getDateValue.
Definition: Helpers.php:31
static flattenSingleValue($value='')
Convert an array to a single scalar value by extracting the first element.
Definition: Functions.php:649
static initialDiff(float $startDate, float $endDate)
Definition: Difference.php:59