Reputation: 11
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:
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.
Upvotes: 1
Views: 3665
Reputation: 245
Using Carbon:
Carbon::parse('2017-10-31')->diffInMonths(Carbon::now());
Upvotes: 0
Reputation: 552
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);
Upvotes: 0
Reputation: 53533
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";
Upvotes: 2