我有两个表格日期:

Start Date: 2007-03-24 
End Date: 2009-06-26

现在我需要通过以下形式找到这两者之间的区别:

2 years, 3 months and 2 days

如何在PHP中执行此操作?


当前回答

您可以使用

getdate()

函数,该函数返回包含所提供日期/时间的所有元素的数组:

$diff = abs($endDate - $startDate);
$my_t=getdate($diff);
print("$my_t[year] years, $my_t[month] months and $my_t[mday] days");

如果开始和结束日期为字符串格式,则使用

$startDate = strtotime($startDateStr);
$endDate = strtotime($endDateStr);

在上述代码之前

其他回答

非常简单:

    <?php
        $date1 = date_create("2007-03-24");
        echo "Start date: ".$date1->format("Y-m-d")."<br>";
        $date2 = date_create("2009-06-26");
        echo "End date: ".$date2->format("Y-m-d")."<br>";
        $diff = date_diff($date1,$date2);
        echo "Difference between start date and end date: ".$diff->format("%y years, %m months and %d days")."<br>";
    ?>

有关详细信息,请查看以下链接:

PHP:date_diff-手动

注意,它适用于PHP 5.3.0或更高版本。

当PHP 5.3(分别为date_diff())不可用时,我使用了我编写的以下函数:

        function dateDifference($startDate, $endDate)
        {
            $startDate = strtotime($startDate);
            $endDate = strtotime($endDate);
            if ($startDate === false || $startDate < 0 || $endDate === false || $endDate < 0 || $startDate > $endDate)
                return false;

            $years = date('Y', $endDate) - date('Y', $startDate);

            $endMonth = date('m', $endDate);
            $startMonth = date('m', $startDate);

            // Calculate months
            $months = $endMonth - $startMonth;
            if ($months <= 0)  {
                $months += 12;
                $years--;
            }
            if ($years < 0)
                return false;

            // Calculate the days
            $measure = ($months == 1) ? 'month' : 'months';
            $days = $endDate - strtotime('+' . $months . ' ' . $measure, $startDate);
            $days = date('z', $days);   

            return array($years, $months, $days);
        }
// If you just want to see the year difference then use this function.
// Using the logic I've created you may also create month and day difference
// which I did not provide here so you may have the efforts to use your brain.
// :)
$date1='2009-01-01';
$date2='2010-01-01';
echo getYearDifference ($date1,$date2);
function getYearDifference($date1=strtotime($date1),$date2=strtotime($date2)){
    $year = 0;
    while($date2 > $date1 = strtotime('+1 year', $date1)){
        ++$year;
    }
    return $year;
}

我想带来一个稍微不同的视角,这似乎没有被提及。

你可以用声明的方式解决这个问题(就像任何其他问题一样)。重点是问你需要什么,而不是如何到达那里。

在这里,你需要与众不同。但这有什么不同?这是一个间隔,正如在最受欢迎的答案中所提到的。问题是如何获取它。您可以不显式调用diff()方法,而是按开始日期和结束日期创建一个间隔,即按日期范围:

$startDate = '2007-03-24';
$endDate = '2009-06-26';
$range = new FromRange(new ISO8601DateTime($startDate), new ISO8601DateTime($endDate));

所有诸如闰年之类的复杂问题都已经解决了。现在,当您有一个固定开始日期时间的间隔时,您可以获得一个人类可读的版本:

var_dump((new HumanReadable($range))->value());

它输出的正是你所需要的。

如果您需要一些自定义格式,这也不是问题。您可以使用ISO8601格式化类,该类接受具有六个参数的调用:年、月、日、小时、分钟和秒:

(new ISO8601Formatted(
    new FromRange(
        new ISO8601DateTime('2017-07-03T14:27:39+00:00'),
        new ISO8601DateTime('2018-07-05T14:27:39.235487+00:00')
    ),
    function (int $years, int $months, int $days, int $hours, int $minutes, int $seconds) {
        return $years >= 1 ? 'More than a year' : 'Less than a year';
    }
))
    ->value();

它的产量超过一年。

有关此方法的更多信息,请查看快速入门条目。

最好的做法是使用PHP的DateTime(和DateInterval)对象。每个日期都封装在DateTime对象中,然后可以在两者之间进行区别:

$first_date = new DateTime("2012-11-30 17:03:30");
$second_date = new DateTime("2012-12-21 00:00:00");

DateTime对象将接受strtotime()的任何格式。如果需要更具体的日期格式,则可以使用DateTime::createFromFormat()创建DateTime对象。

两个对象实例化后,使用DateTime::diff()从另一个对象中减去一个对象。

$difference = $first_date->diff($second_date);

$difference现在保存一个包含差异信息的DateInterval对象。var_dump()如下所示:

object(DateInterval)
  public 'y' => int 0
  public 'm' => int 0
  public 'd' => int 20
  public 'h' => int 6
  public 'i' => int 56
  public 's' => int 30
  public 'invert' => int 0
  public 'days' => int 20

要格式化DateInterval对象,我们需要检查每个值,如果值为0,则将其排除:

/**
 * Format an interval to show all existing components.
 * If the interval doesn't have a time component (years, months, etc)
 * That component won't be displayed.
 *
 * @param DateInterval $interval The interval
 *
 * @return string Formatted interval string.
 */
function format_interval(DateInterval $interval) {
    $result = "";
    if ($interval->y) { $result .= $interval->format("%y years "); }
    if ($interval->m) { $result .= $interval->format("%m months "); }
    if ($interval->d) { $result .= $interval->format("%d days "); }
    if ($interval->h) { $result .= $interval->format("%h hours "); }
    if ($interval->i) { $result .= $interval->format("%i minutes "); }
    if ($interval->s) { $result .= $interval->format("%s seconds "); }

    return $result;
}

现在剩下的就是调用$differenceDateInterval对象上的函数:

echo format_interval($difference);

我们得到了正确的结果:

20天6小时56分30秒

用于实现目标的完整代码:

/**
 * Format an interval to show all existing components.
 * If the interval doesn't have a time component (years, months, etc)
 * That component won't be displayed.
 *
 * @param DateInterval $interval The interval
 *
 * @return string Formatted interval string.
 */
function format_interval(DateInterval $interval) {
    $result = "";
    if ($interval->y) { $result .= $interval->format("%y years "); }
    if ($interval->m) { $result .= $interval->format("%m months "); }
    if ($interval->d) { $result .= $interval->format("%d days "); }
    if ($interval->h) { $result .= $interval->format("%h hours "); }
    if ($interval->i) { $result .= $interval->format("%i minutes "); }
    if ($interval->s) { $result .= $interval->format("%s seconds "); }

    return $result;
}

$first_date = new DateTime("2012-11-30 17:03:30");
$second_date = new DateTime("2012-12-21 00:00:00");

$difference = $first_date->diff($second_date);

echo format_interval($difference);