Home > OS >  DateTime:diff in PHP returns different results between same cases
DateTime:diff in PHP returns different results between same cases

Time:12-05

Here is my code. Can somebody explain me please the reason of these two cases given different results which is not expected.

$d1 = new DateTime("2021-11-30 00:00:00");
$d2 = new DateTime("2022-03-01 00:00:00");

var_dump($d1->diff($d2, true)->m);
var_dump($d2->diff($d1, true)->m);

// Results:
// int(2)
// int(3)

You can reproduce it on the online Sandbox: http://sandbox.onlinephpfunctions.com/code/23f0c79396004fa7300887f1fc97683829fd1421

CodePudding user response:

I found this is a bug in php but it's explained like the following when you run this:

$d1 = new DateTime("2021-11-30 00:00:00");
$d2 = new DateTime("2022-03-01 00:00:00");
var_dump($d1->diff($d2, true)->m);

php starts to count number of months starting with this date 2021-11-30 by counting how many day with number 30 they had to reach it's point you will find then 30th of Dec. and 30th of Jan. that's why you got number of months as 2

In the other side when you run this:

$d1 = new DateTime("2021-11-30 00:00:00");
$d2 = new DateTime("2022-03-01 00:00:00");
var_dump($d2->diff($d1, true)->m);

you will start from day number 1 of the months so you will find 1th of Feb, 1th of Jan and 1th of Dec that's why you get 3 months

Update you can simply do this using days:

$d1 = new DateTime("2021-11-30 00:00:00");
$d2 = new DateTime("2022-03-01 00:00:00");
var_dump(intval($d1->diff($d2, true)->days/30));
var_dump(intval($d2->diff($d1, true)->days/30));

the two of them will give you 3 months

CodePudding user response:

Adding and subtracting months from dates is non-trivial, because months do not all have the same number of days, so you cannot rely on it to give you the answer you expect.

If you add 1 month to 30 January, you get 2 March, because there are only 28 days in February. Adding 3 months to 30 November has the same effect.

echo (new DateTime('2022-11-30'))->modify(' 3 month')->format('Y-m-d');
# 2022-03-02

Whereas if you subtract 1 month from 2 March, you get 2 February! Which is logical (how could you possibly get 30 January?) if confusing. This is why subtracting 3 months gives you 2 December.

echo (new DateTime('2021-11-30'))->modify(' 3 month')->modify('-3 month')->format('Y-m-d');
# 2021-12-02

This may seem surprising, but the alternative is equally confusing. If one month after 30 January was 28 February, subtracting one month from that still wouldn't give you the date you started with.

It therefore follows that the difference between 11 November and 1 February cannot be more than 3 months, because 3 months would give you 2 February. And also that the reverse diff is more than 3 months, because 3 months would give you 1 December! All completely maddening, but depending on what you actually mean by "how many months are there between these dates", you can probably work around it, by calculating the difference between the first of each month, or by doing something based on the answers to this question.

  • Related