php - Carbon Objects diffInMonths showing 0 when one date is 1st Nov and the other 1st Dec
I have two carbon objects
//$startDate
Carbon\Carbon @1667250000 {#3093 ?�?
date: 2022-11-01 00:00:00.0 Africa/Nairobi (+03:00)
}
and
//$endDate
Carbon\Carbon @1669842000 {#2920 ?�?
date: 2022-12-01 00:00:00.0 Africa/Nairobi (+03:00)
}
when I run dateDiffInMonths() on them I get 0 but I expect 1
$startDate->diffInMonths($endDate); //0
I have tried adding floorMonth() to objects but the answer is still the same.
When I get $startDate->diff($endDate)
I get the following with days difference as 30
DateInterval {#3102 ?�?
interval: + 30d
+"y": 0
+"m": 0
+"d": 30
+"h": 0
+"i": 0
+"s": 0
+"f": 0.0
}
What am I doing wrong?
Answer
Solution:
There are always bugs with DateTime in various PHP versions. These also affect carbon. I've been using this algorithm for years (from https://github.com/jspit-de/dt/blob/master/Dt.php#L1284):
function diffInMonth(DateTime $start,DateTime $end): int {
$endDate = (clone $end)->setTimeZone($start->getTimeZone());
list($yearStart,$monthStart,$dayStart) = explode(" ",$start->format("Y m dHis"));
list($yearEnd,$monthEnd, $dayEnd) = explode(" ",$endDate->format("Y m dHis"));
$mothDiff = ($yearEnd - $yearStart) * 12 + $monthEnd - $monthStart;
if($dayStart > $dayEnd && $end >= $start) --$mothDiff;
elseif($dayStart < $dayEnd && $end < $start) ++$mothDiff;
return $mothDiff;
}
$startDate = new DateTime('2022-11-01 00:00:00.0', new DateTimeZone('Africa/Nairobi'));
$endDate = new DateTime('2022-12-01 00:00:00.0', new DateTimeZone('Africa/Nairobi'));
$month = diffInMonth($startDate, $endDate);
echo ' Positve: '.$month."\n"; //1
$month = diffInMonth($endDate,$startDate);
echo " Negative: ".$month; //-1
Demo + Test: https://3v4l.org/Tgqcf
This function works the same way with carbon objects.
Source