From 7ed96e0be15ef292bc05283b3f6122fc0f28968b Mon Sep 17 00:00:00 2001 From: Alban Duval Date: Mon, 25 May 2020 21:33:48 +0200 Subject: [PATCH] Calcualtion - DATEDIF - fix result for Y & YM units (#1466) Bugfix for negative results and too small results 2000-02-02 => 2001-02-01 > DATEDIF with Y unit: 0 year (returned -1 before fix) > DATEDIF with YM unit: 11 months (returned -1 before fix) --- src/PhpSpreadsheet/Calculation/DateTime.php | 30 +++++---------------- tests/data/Calculation/DateTime/DATEDIF.php | 14 +++++++++- 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/src/PhpSpreadsheet/Calculation/DateTime.php b/src/PhpSpreadsheet/Calculation/DateTime.php index d08ab543..19860794 100644 --- a/src/PhpSpreadsheet/Calculation/DateTime.php +++ b/src/PhpSpreadsheet/Calculation/DateTime.php @@ -668,30 +668,19 @@ class DateTime $endMonths = $PHPEndDateObject->format('n'); $endYears = $PHPEndDateObject->format('Y'); + $PHPDiffDateObject = $PHPEndDateObject->diff($PHPStartDateObject); + switch ($unit) { case 'D': $retVal = (int) $difference; break; case 'M': - $retVal = (int) ($endMonths - $startMonths) + ((int) ($endYears - $startYears) * 12); - // We're only interested in full months - if ($endDays < $startDays) { - --$retVal; - } + $retVal = (int) 12 * $PHPDiffDateObject->format('%y') + $PHPDiffDateObject->format('%m'); break; case 'Y': - $retVal = (int) ($endYears - $startYears); - // We're only interested in full months - if ($endMonths < $startMonths) { - --$retVal; - } elseif (($endMonths == $startMonths) && ($endDays < $startDays)) { - // Remove start month - --$retVal; - // Remove end month - --$retVal; - } + $retVal = (int) $PHPDiffDateObject->format('%y'); break; case 'MD': @@ -701,19 +690,12 @@ class DateTime $adjustDays = $PHPEndDateObject->format('j'); $retVal += ($adjustDays - $startDays); } else { - $retVal = $endDays - $startDays; + $retVal = (int) $PHPDiffDateObject->format('%d'); } break; case 'YM': - $retVal = (int) ($endMonths - $startMonths); - if ($retVal < 0) { - $retVal += 12; - } - // We're only interested in full months - if ($endDays < $startDays) { - --$retVal; - } + $retVal = (int) $PHPDiffDateObject->format('%m'); break; case 'YD': diff --git a/tests/data/Calculation/DateTime/DATEDIF.php b/tests/data/Calculation/DateTime/DATEDIF.php index d113d3aa..a6d2d761 100644 --- a/tests/data/Calculation/DateTime/DATEDIF.php +++ b/tests/data/Calculation/DateTime/DATEDIF.php @@ -393,6 +393,10 @@ return [ 1, '19-12-1960', '26-01-2012', 'YM', ], + [ + 11, + '19-12-1960', '26-11-1962', 'YM', + ], [ 38, '19-12-1960', '26-01-2012', 'YD', @@ -402,7 +406,15 @@ return [ '19-12-1960', '26-01-2012', 'MD', ], [ - 50, + 0, + '19-12-1960', '12-12-1961', 'Y', + ], + [ + 1, + '19-12-1960', '12-12-1962', 'Y', + ], + [ + 51, '19-12-1960', '12-12-2012', 'Y', ], [