我有两个表格日期:

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

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

2 years, 3 months and 2 days

如何在PHP中执行此操作?


当前回答

非常简单:

    <?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或更高版本。

其他回答

使用示例:

echo time_diff_string('2013-05-01 00:22:35', 'now');
echo time_diff_string('2013-05-01 00:22:35', 'now', true);

输出:

4 months ago
4 months, 2 weeks, 3 days, 1 hour, 49 minutes, 15 seconds ago

功能:

function time_diff_string($from, $to, $full = false) {
    $from = new DateTime($from);
    $to = new DateTime($to);
    $diff = $to->diff($from);

    $diff->w = floor($diff->d / 7);
    $diff->d -= $diff->w * 7;

    $string = array(
        'y' => 'year',
        'm' => 'month',
        'w' => 'week',
        'd' => 'day',
        'h' => 'hour',
        'i' => 'minute',
        's' => 'second',
    );
    foreach ($string as $k => &$v) {
        if ($diff->$k) {
            $v = $diff->$k . ' ' . $v . ($diff->$k > 1 ? 's' : '');
        } else {
            unset($string[$k]);
        }
    }

    if (!$full) $string = array_slice($string, 0, 1);
    return $string ? implode(', ', $string) . ' ago' : 'just now';
}

对于php版本>=5.3:创建两个日期对象,然后使用date_diff()函数。它将返回phpDateInterval对象。请参阅文档

$date1=date_create("2007-03-24");
$date2=date_create("2009-06-26");
$diff=date_diff($date1,$date2);
echo $diff->format("%R%a days");

我不知道你是否在使用PHP框架,但很多PHP框架都有日期/时间库和助手来帮助你避免重新发明轮子。

例如,CodeIgniter具有timespan()函数。只需输入两个Unix时间戳,就会自动生成如下结果:

1 Year, 10 Months, 2 Weeks, 5 Days, 10 Hours, 16 Minutes

http://codeigniter.com/user_guide/helpers/date_helper.html

前段时间,我编写了一个format_date函数,因为它提供了许多关于日期的选项:

function format_date($date, $type, $seperator="-")
{
    if($date)
    {
        $day = date("j", strtotime($date));
        $month = date("n", strtotime($date));
        $year = date("Y", strtotime($date));
        $hour = date("H", strtotime($date));
        $min = date("i", strtotime($date));
        $sec = date("s", strtotime($date));

        switch($type)
        {
            case 0:  $date = date("Y".$seperator."m".$seperator."d",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 1:  $date = date("D, F j, Y",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 2:  $date = date("d".$seperator."m".$seperator."Y",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 3:  $date = date("d".$seperator."M".$seperator."Y",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 4:  $date = date("d".$seperator."M".$seperator."Y h:i A",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 5:  $date = date("m".$seperator."d".$seperator."Y",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 6:  $date = date("M",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 7:  $date = date("Y",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 8:  $date = date("j",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 9:  $date = date("n",mktime($hour, $min, $sec, $month, $day, $year)); break;
            case 10: 
                     $diff = abs(strtotime($date) - strtotime(date("Y-m-d h:i:s"))); 
                     $years = floor($diff / (365*60*60*24));
                     $months = floor(($diff - $years * 365*60*60*24) / (30*60*60*24));
                     $days = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24)/ (60*60*24));
                     $date = $years . " years, " . $months . " months, " . $days . "days";
        }
    }
    return($date);
}    

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

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

在这里,你需要与众不同。但这有什么不同?这是一个间隔,正如在最受欢迎的答案中所提到的。问题是如何获取它。您可以不显式调用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();

它的产量超过一年。

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