briannesbitt / Carbon

A simple PHP API extension for DateTime.

Home Page:https://carbon.nesbot.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

commented

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