Differences Between: [Versions 400 and 401] [Versions 400 and 402] [Versions 400 and 403]
1 <?php 2 3 namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel; 4 5 use DateInterval; 6 use DateTime; 7 use PhpOffice\PhpSpreadsheet\Calculation\Exception; 8 use PhpOffice\PhpSpreadsheet\Calculation\Functions; 9 use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper; 10 11 class Difference 12 { 13 /** 14 * DATEDIF. 15 * 16 * @param mixed $startDate Excel date serial value, PHP date/time stamp, PHP DateTime object 17 * or a standard date string 18 * @param mixed $endDate Excel date serial value, PHP date/time stamp, PHP DateTime object 19 * or a standard date string 20 * @param string $unit 21 * 22 * @return int|string Interval between the dates 23 */ 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 69 /** 70 * Decide whether it's time to set retVal. 71 * 72 * @param bool|int $retVal 73 * 74 * @return null|bool|int 75 */ 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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body