Carbon v3 diffInDays is not consistent
rbzachary opened this issue · comments
Hello,
I encountered an issue with the following code:
echo Carbon::parse('2024-03-01', "America/New_York")->addDays(10)->diffInDays(Carbon::parse('2024-03-01', "America/New_York"));
echo Carbon::parse('2024-04-01', "America/New_York")->addDays(10)->diffInDays(Carbon::parse('2024-04-01', "America/New_York"));
Carbon version: 3.1.1
PHP version: 8.1.23
I expected to get:
-10
-10
But I actually get:
-9.9583333333333
-10
So, technically it is correct that it is fewer than 10 days between midnight on March 1 and March 11 in Eastern Time; however there are situations where you are dealing with 2 dates where you want to get the difference between the two and it isn't always obvious why you aren't getting the correct results.
Thanks!
I see different results as well in Laravel
Laravel 10 with Carbon 2
> now()->addMonths(12)->diffInMinutes(now())
= 525599
Laravel 11 with Carbon 3
> now()->addMonths(12)->diffInMinutes(now())
= -525599.99999737
Notice carbon 3 results in negative value
P.S - All of diff methods are resulting in negative values
Related #2119
Hello @ankurk91 it's a different concern.
The difference in the original post above happens because of daylight saving time (I'm currently evaluating how to best handle that so the result may change in the future).
But the difference you get is expected, in Carbon 2, the diff was always int
(truncated down) and by default $absolute = true
so you don't have the notion of which date is earlier, in Carbon 3 the entire value including sign, decimal part is kept and so you can decide on your side what you want or not.
P.S - All of diff methods are resulting in negative values
No $a->diffInMinutes($b)
returns negative values only if $a > $b
If you want positive/absolute value, you can use one of the options below:
// Swapping dates so current < other
$value = now()->diffInMinutes(now()->addMonths(12));
// Explicit absolute so it's positive no matter if other is > or < than current
$value = now()->addMonths(12)->diffInMinutes(now(), true);
$value = abs(now()->addMonths(12)->diffInMinutes(now()));
Then from this $value
if you don't want the decimal part, it's up to you to decide if you prefer: floor($value)
, round($value)
or ceil($value)
.
Thank you for this, and also for taking care of it so quickly