Hướng dẫn month difference in php

Is there any way to find the month difference in PHP? I have the input of from-date 2003-10-17 and to-date 2004-03-24. I need to find how many months there are within these two days. Say if 6 months, I need the output in months only. Thanks for guiding me for day difference.

I find the solution through MySQL but I need it in PHP. Anyone help me, Thanks in advance.

S.L. Barth

8,08971 gold badges50 silver badges63 bronze badges

asked Apr 21, 2010 at 9:08

2

The easiest way without reinventing the wheel. This'll give you the full months difference. I.e. the below two dates are almost 76 months apart, but the result is 75 months.

date_default_timezone_set['Asia/Tokyo'];  // you are required to set a timezone

$date1 = new DateTime['2009-08-12'];
$date2 = new DateTime['2003-04-14'];

$diff = $date1->diff[$date2];

echo [[$diff->format['%y'] * 12] + $diff->format['%m']] . " full months difference";

answered Apr 21, 2010 at 9:52

decezedeceze

497k81 gold badges718 silver badges865 bronze badges

10

After testing tons of solutions, putting all in a unit test, this is what I come out with:

/**
 * Calculate the difference in months between two dates [v1 / 18.11.2013]
 *
 * @param \DateTime $date1
 * @param \DateTime $date2
 * @return int
 */
public static function diffInMonths[\DateTime $date1, \DateTime $date2]
{
    $diff =  $date1->diff[$date2];

    $months = $diff->y * 12 + $diff->m + $diff->d / 30;

    return [int] round[$months];
}

For example it will return [test cases from the unit test]:

  • 01.11.2013 - 30.11.2013 - 1 month
  • 01.01.2013 - 31.12.2013 - 12 months
  • 31.01.2011 - 28.02.2011 - 1 month
  • 01.09.2009 - 01.05.2010 - 8 months
  • 01.01.2013 - 31.03.2013 - 3 months
  • 15.02.2013 - 15.04.2013 - 2 months
  • 01.02.1985 - 31.12.2013 - 347 months

Notice: Because of the rounding it does with the days, even a half of a month will be rounded, which may lead to issue if you use it with some cases. So DO NOT USE it for such cases, it will cause you issues.

For example:

  • 02.11.2013 - 31.12.2013 will return 2, not 1 [as expected].

answered Nov 18, 2013 at 11:53

Valentin DespaValentin Despa

38.1k18 gold badges79 silver badges103 bronze badges

2

I just wanted to add this if anyone is looking for a simple solution that counts each touched-upon month in stead of complete months, rounded months or something like that.

// Build example data
$timeStart = strtotime["2003-10-17"];
$timeEnd = strtotime["2004-03-24"];
// Adding current month + all months in each passed year
$numMonths = 1 + [date["Y",$timeEnd]-date["Y",$timeStart]]*12;
// Add/subtract month difference
$numMonths += date["m",$timeEnd]-date["m",$timeStart];

echo $numMonths;

answered Mar 13, 2015 at 8:05

MaXMaX

1,68513 silver badges17 bronze badges

Wow, way to overthink the problem... How about this version:

function monthsBetween[$startDate, $endDate] {
    $retval = "";

    // Assume YYYY-mm-dd - as is common MYSQL format
    $splitStart = explode['-', $startDate];
    $splitEnd = explode['-', $endDate];

    if [is_array[$splitStart] && is_array[$splitEnd]] {
        $difYears = $splitEnd[0] - $splitStart[0];
        $difMonths = $splitEnd[1] - $splitStart[1];
        $difDays = $splitEnd[2] - $splitStart[2];

        $retval = [$difDays > 0] ? $difMonths : $difMonths - 1;
        $retval += $difYears * 12;
    }
    return $retval;
}

NB: unlike several of the other solutions, this doesn't depend on the date functions added in PHP 5.3, since many shared hosts aren't there yet.

answered Mar 11, 2012 at 22:21

CLWillCLWill

1481 silver badge5 bronze badges

2

$datetime1 = date_create['2009-10-11'];

$datetime2 = date_create['2013-1-13'];

$interval = date_diff[$datetime1, $datetime2];

echo $interval->format['%a day %m month %y year'];

answered Oct 6, 2016 at 6:41

2

// get year and month difference

$a1 = '20170401';

$a2 = '20160101'

$yearDiff = [substr[$a1, 0, 4] - substr[$a2, 0, 4]];

$monthDiff = [substr[$a1, 4, 2] - substr[$a2, 4, 2]];

$fullMonthDiff = [$yearDiff * 12] + $monthDiff;

// fullMonthDiff = 16

Mikhail_Sam

9,55611 gold badges57 silver badges87 bronze badges

answered Dec 17, 2015 at 10:43

This is my enhanced version of @deceze answer:

 /**
 * @param string $startDate
 * Current date is considered if empty string is passed
 * @param string $endDate
 * Current date is considered if empty string is passed
 * @param bool $unsigned
 * If $unsigned is true, difference is always positive, otherwise the difference might be negative
 * @return int
 */
public static function diffInFullMonths[$startDate, $endDate, $unsigned = false]
{
    $diff = [new DateTime[$startDate]]->diff[new DateTime[$endDate]];
    $reverse = $unsigned === true ? '' : '%r';
    return [[int] $diff->format["{$reverse}%y"] * 12] + [[int] $diff->format["{$reverse}%m"]];
}

answered Jan 6, 2016 at 2:39

EhsanEhsan

99210 silver badges19 bronze badges

The best way.

function getIntervals[DateTime $from, DateTime $to]
{
    $intervals = [];
    $startDate = $from->modify['first day of this month'];
    $endDate = $to->modify['last day of this month'];
    while[$startDate < $endDate]{
        $firstDay = $startDate->format['Y-m-d H:i:s'];
        $startDate->modify['last day of this month']->modify['+1 day'];
        $intervals[] = [
            'firstDay' => $firstDay,
            'lastDay' => $startDate->modify['-1 second']->format['Y-m-d H:i:s'],
        ];
        $startDate->modify['+1 second'];
    }
    return $intervals;
}
$dateTimeFirst = new \DateTime['2013-01-01'];
$dateTimeSecond = new \DateTime['2013-03-31'];
$interval = getIntervals[$dateTimeFirst, $dateTimeSecond];
print_r[$interval];

Result:

Array
[
    [0] => Array
        [
            [firstDay] => 2013-01-01 00:00:00
            [lastDay] => 2013-01-31 23:59:59
        ]

    [1] => Array
        [
            [firstDay] => 2013-02-01 00:00:00
            [lastDay] => 2013-02-28 23:59:59
        ]

    [2] => Array
        [
            [firstDay] => 2013-03-01 00:00:00
            [lastDay] => 2013-03-31 23:59:59
        ]

]

answered Feb 18, 2016 at 8:56

LebnikLebnik

6318 silver badges11 bronze badges

In my case I needed to count full months and day leftovers as month as well to build a line chart labels.

/**
 * Calculate the difference in months between two dates
 *
 * @param \DateTime $from
 * @param \DateTime $to
 * @return int
 */
public static function diffInMonths[\DateTime $from, \DateTime $to]
{
    // Count months from year and month diff
    $diff = $to->diff[$from]->format['%y'] * 12 + $to->diff[$from]->format['%m'];

    // If there is some day leftover, count it as the full month
    if [$to->diff[$from]->format['%d'] > 0] $diff++;

    // The month count isn't still right in some cases. This covers it.
    if [$from->format['d'] >= $to->format['d']] $diff++;
}

answered Mar 11, 2016 at 8:30

John LinhartJohn Linhart

1,61619 silver badges21 bronze badges


Reference: //au.php.net/manual/en/function.mktime.php#86916

answered Apr 21, 2010 at 9:32

Russell DiasRussell Dias

68.4k5 gold badges50 silver badges71 bronze badges

1

function monthsDif[$start, $end]
{
    // Assume YYYY-mm-dd - as is common MYSQL format
    $splitStart = explode['-', $start];
    $splitEnd = explode['-', $end];

    if [is_array[$splitStart] && is_array[$splitEnd]] {
        $startYear = $splitStart[0];
        $startMonth = $splitStart[1];
        $endYear = $splitEnd[0];
        $endMonth = $splitEnd[1];

        $difYears = $endYear - $startYear;
        $difMonth = $endMonth - $startMonth;

        if [0 == $difYears && 0 == $difMonth] { // month and year are same
            return 0;
        }
        else if [0 == $difYears && $difMonth > 0] { // same year, dif months
            return $difMonth;
        }
        else if [1 == $difYears] {
            $startToEnd = 13 - $startMonth; // months remaining in start year[13 to include final month
            return [$startToEnd + $endMonth]; // above + end month date
        }
        else if [$difYears > 1] {
            $startToEnd = 13 - $startMonth; // months remaining in start year 
            $yearsRemaing = $difYears - 2;  // minus the years of the start and the end year
            $remainingMonths = 12 * $yearsRemaing; // tally up remaining months
            $totalMonths = $startToEnd + $remainingMonths + $endMonth; // Monthsleft + full years in between + months of last year
            return $totalMonths;
        }
    }
    else {
        return false;
    }
}

answered Jan 11, 2012 at 17:14

1

Here's a quick one:

$date1 = mktime[0,0,0,10,0,2003]; // m d y, use 0 for day
$date2 = mktime[0,0,0,3,0,2004]; // m d y, use 0 for day

echo round[[$date2-$date1] / 60 / 60 / 24 / 30];

answered Apr 21, 2010 at 9:19

TowerTower

94.9k126 gold badges346 silver badges502 bronze badges

2

Not the answer you're looking for? Browse other questions tagged php datetime date or ask your own question.

Chủ Đề