1

I am trying to calculate the difference in months between two dates, but in a more specific way.

For example, I have two dates: 2017-11-01 and 2018-01-31 What I need as a result is 3 months. Meaning, there are 3 full billing months between these two dates.

Here is how it's supposed to work:

  • Month 1: 2017-11-01 until 2017-11-30
  • Month 2: 2017-12-01 until 2017-12-31
  • Month 3: 2018-01-01 until 2018-01-31

I have tried the diff method in the DateTime class, it produces something that doesn't help much. Here is an example

<?php
$date1 = DateTime::createFromFormat('Y-m-d H:i:s', '2017-11-01 00:00:00');
$date2 = DateTime::createFromFormat('Y-m-d H:i:s', '2018-01-31 00:00:00');
$diff = $date1->diff($date2);
print_r($diff)

result:
DateInterval Object
(
    [y] => 0
    [m] => 2
    [d] => 30
    [h] => 0
    [i] => 0
    [s] => 0
    [weekday] => 0
    [weekday_behavior] => 0
    [first_last_day_of] => 0
    [invert] => 0
    [days] => 91
    [special_type] => 0
    [special_amount] => 0
    [have_weekday_relative] => 0
    [have_special_relative] => 0
)

It shows 2 months and 30 days.

However, in a slightly different scenario

$date1 = DateTime::createFromFormat('Y-m-d H:i:s', '2017-11-01 00:00:00');
$date2 = DateTime::createFromFormat('Y-m-d H:i:s', '2018-01-30 00:00:00');

The diff between these two dates should show 2 months and 30 days, not 3 months.

Any help or ideas would be greatly appreciated.

Lulzim
  • 11
  • 1
  • 2
  • Possible duplicate of [Calculate difference between two dates (number of days)?](https://stackoverflow.com/questions/1607336/calculate-difference-between-two-dates-number-of-days) – 534F Oct 31 '17 at 20:19
  • @534F - This question is about PHP. Your link is about C#. – Obsidian Age Oct 31 '17 at 20:20
  • 2
    Possible duplicate of [How to calculate the difference between two dates using PHP?](https://stackoverflow.com/questions/676824/how-to-calculate-the-difference-between-two-dates-using-php) – Mohit Oct 31 '17 at 20:24
  • Sorry for wrong tagging, first time poster. Oh and I did search a lot before posting, but couldn't find anything. It is not a duplicate of any of those – Lulzim Oct 31 '17 at 20:31
  • Just be careful with including hours, as DST can really make a mess of things twice a year... – IncredibleHat Oct 31 '17 at 20:37

3 Answers3

2

Add one day to your ending date before doing the comparison. If the original ending date was the last day of the month, then the new ending date will roll over to the next month and you'll get the correct number of "full" months in the diff object. If the original was any day but the last day of the month, it won't change the result.

$start = '2017-11-01';
$end = '2018-01-31';

$date1 = DateTime::createFromFormat('Y-m-d', $start);
$date2 = DateTime::createFromFormat('Y-m-d', $end)->add(new DateInterval('P1D'));

echo $date1->diff($date2)->m, "\n";
Alex Howansky
  • 50,515
  • 8
  • 78
  • 98
  • The last day is not included because the time in both `DateTime` instances is the current one (since it isn't specified), so the last day isn't quite "counted". A better solution, in case he needs to use `$date2`, is to do `$date1->setTime(0, 0, 0); $date2->setTime(0, 0, 1);`, instead of adding a day. – ishegg Oct 31 '17 at 20:40
  • That does not achieve the desired result. OP needs `$diff->m` to count a full month in the diff result if the last day of the range is on the last day of the month it's in -- which `diff()` does not do, regardless of the time. – Alex Howansky Oct 31 '17 at 20:48
0

Seems you lost one day during your calculation. Cause you need interval in months including first/last day - then you should add this day to interval.

So, the solution in this case will be:

$date1 = DateTime::createFromFormat('Y-m-d H:i:s', '2017-11-01 00:00:00');
$date2 = DateTime::createFromFormat('Y-m-d H:i:s', '2018-01-31 23:59:59');
$diff = $date1->diff($date2);

or:

$date1 = DateTime::createFromFormat('Y-m-d H:i:s', '2017-10-31 00:00:00');
$date2 = DateTime::createFromFormat('Y-m-d H:i:s', '2018-01-31 00:00:00');
$diff = $date1->diff($date2);

or even:

$date1 = DateTime::createFromFormat('Y-m-d H:i:s', '2017-11-01 00:00:00');
$date2 = DateTime::createFromFormat('Y-m-d H:i:s', '2018-02-01 00:00:00');
$diff = $date1->diff($date2);
Lexxusss
  • 542
  • 4
  • 10
0

Using Carbon:

Carbon::parse('2017-10-31')->diffInMonths(Carbon::now());
simon.ro
  • 2,984
  • 2
  • 22
  • 36