ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
YearFrac.php
Go to the documentation of this file.
1 <?php
2 
4 
8 
9 class YearFrac
10 {
37  public static function fraction($startDate, $endDate, $method = 0)
38  {
39  try {
40  $method = (int) Helpers::validateNumericNull($method);
41  $sDate = Helpers::getDateValue($startDate);
42  $eDate = Helpers::getDateValue($endDate);
43  $sDate = self::excelBug($sDate, $startDate, $endDate, $method);
44  $eDate = self::excelBug($eDate, $endDate, $startDate, $method);
45  $startDate = min($sDate, $eDate);
46  $endDate = max($sDate, $eDate);
47  } catch (Exception $e) {
48  return $e->getMessage();
49  }
50 
51  switch ($method) {
52  case 0:
53  return Days360::between($startDate, $endDate) / 360;
54  case 1:
55  return self::method1($startDate, $endDate);
56  case 2:
57  return Difference::interval($startDate, $endDate) / 360;
58  case 3:
59  return Difference::interval($startDate, $endDate) / 365;
60  case 4:
61  return Days360::between($startDate, $endDate, true) / 360;
62  }
63 
64  return Functions::NAN();
65  }
66 
73  private static function excelBug(float $sDate, $startDate, $endDate, int $method): float
74  {
75  if (Functions::getCompatibilityMode() !== Functions::COMPATIBILITY_OPENOFFICE && SharedDateHelper::getExcelCalendar() !== SharedDateHelper::CALENDAR_MAC_1904) {
76  if ($endDate === null && $startDate !== null) {
77  if (DateParts::month($sDate) == 12 && DateParts::day($sDate) === 31 && $method === 0) {
78  $sDate += 2;
79  } else {
80  ++$sDate;
81  }
82  }
83  }
84 
85  return $sDate;
86  }
87 
88  private static function method1(float $startDate, float $endDate): float
89  {
90  $days = Difference::interval($startDate, $endDate);
91  $startYear = (int) DateParts::year($startDate);
92  $endYear = (int) DateParts::year($endDate);
93  $years = $endYear - $startYear + 1;
94  $startMonth = (int) DateParts::month($startDate);
95  $startDay = (int) DateParts::day($startDate);
96  $endMonth = (int) DateParts::month($endDate);
97  $endDay = (int) DateParts::day($endDate);
98  $startMonthDay = 100 * $startMonth + $startDay;
99  $endMonthDay = 100 * $endMonth + $endDay;
100  if ($years == 1) {
101  $tmpCalcAnnualBasis = 365 + (int) Helpers::isLeapYear($endYear);
102  } elseif ($years == 2 && $startMonthDay >= $endMonthDay) {
103  if (Helpers::isLeapYear($startYear)) {
104  $tmpCalcAnnualBasis = 365 + (int) ($startMonthDay <= 229);
105  } elseif (Helpers::isLeapYear($endYear)) {
106  $tmpCalcAnnualBasis = 365 + (int) ($endMonthDay >= 229);
107  } else {
108  $tmpCalcAnnualBasis = 365;
109  }
110  } else {
111  $tmpCalcAnnualBasis = 0;
112  for ($year = $startYear; $year <= $endYear; ++$year) {
113  $tmpCalcAnnualBasis += 365 + (int) Helpers::isLeapYear($year);
114  }
115  $tmpCalcAnnualBasis /= $years;
116  }
117 
118  return $days / $tmpCalcAnnualBasis;
119  }
120 }
static interval($startDate, $endDate, $unit='D')
DATEDIF.
Definition: Difference.php:24
static fraction($startDate, $endDate, $method=0)
YEARFRAC.
Definition: YearFrac.php:37
static isLeapYear($year)
Identify if a year is a leap year or not.
Definition: Helpers.php:19
static getDateValue($dateValue, bool $allowBool=true)
getDateValue.
Definition: Helpers.php:31
static between($startDate=0, $endDate=0, $method=false)
DAYS360.
Definition: Days360.php:39
static excelBug(float $sDate, $startDate, $endDate, int $method)
Excel 1900 calendar treats date argument of null as 1900-01-00.
Definition: YearFrac.php:73
static validateNumericNull($number)
Many functions accept null argument treated as 0.
Definition: Helpers.php:243
static method1(float $startDate, float $endDate)
Definition: YearFrac.php:88
static getCompatibilityMode()
Return the current Compatibility Mode.
Definition: Functions.php:93