我有两个表格日期:
Start Date: 2007-03-24
End Date: 2009-06-26
现在我需要通过以下形式找到这两者之间的区别:
2 years, 3 months and 2 days
如何在PHP中执行此操作?
我有两个表格日期:
Start Date: 2007-03-24
End Date: 2009-06-26
现在我需要通过以下形式找到这两者之间的区别:
2 years, 3 months and 2 days
如何在PHP中执行此操作?
当前回答
当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);
}
其他回答
最好的做法是使用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);
这是可运行的代码
$date1 = date_create('2007-03-24');
$date2 = date_create('2009-06-26');
$diff1 = date_diff($date1,$date2);
$daysdiff = $diff1->format("%R%a");
$daysdiff = abs($daysdiff);
我在PHP5.2中遇到了同样的问题,并用MySQL解决了这个问题。可能并不是你想要的,但这会奏效,并返回天数:
$datediff_q = $dbh->prepare("SELECT DATEDIFF(:date2, :date1)");
$datediff_q->bindValue(':date1', '2007-03-24', PDO::PARAM_STR);
$datediff_q->bindValue(':date2', '2009-06-26', PDO::PARAM_STR);
$datediff = ($datediff_q->execute()) ? $datediff_q->fetchColumn(0) : false;
此处有更多信息http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_datediff
我投票支持jurka的答案,因为这是我最喜欢的,但我有一个pre-php.5.3版本。。。
我发现自己在解决一个类似的问题——这就是我最初如何回答这个问题——但只是需要时间上的差异。但我的函数也很好地解决了这个问题,而且我自己的库中没有任何地方可以将它保存在不会丢失和遗忘的地方,所以……希望这对某人有用。
/**
*
* @param DateTime $oDate1
* @param DateTime $oDate2
* @return array
*/
function date_diff_array(DateTime $oDate1, DateTime $oDate2) {
$aIntervals = array(
'year' => 0,
'month' => 0,
'week' => 0,
'day' => 0,
'hour' => 0,
'minute' => 0,
'second' => 0,
);
foreach($aIntervals as $sInterval => &$iInterval) {
while($oDate1 <= $oDate2){
$oDate1->modify('+1 ' . $sInterval);
if ($oDate1 > $oDate2) {
$oDate1->modify('-1 ' . $sInterval);
break;
} else {
$iInterval++;
}
}
}
return $aIntervals;
}
测试:
$oDate = new DateTime();
$oDate->modify('+111402189 seconds');
var_dump($oDate);
var_dump(date_diff_array(new DateTime(), $oDate));
结果是:
object(DateTime)[2]
public 'date' => string '2014-04-29 18:52:51' (length=19)
public 'timezone_type' => int 3
public 'timezone' => string 'America/New_York' (length=16)
array
'year' => int 3
'month' => int 6
'week' => int 1
'day' => int 4
'hour' => int 9
'minute' => int 3
'second' => int 8
我从这里得到了最初的想法,我对其进行了修改以供使用(我希望我的修改也会显示在该页面上)。
通过从$aIntervals数组中删除不需要的间隔(例如“周”),或者添加$aExclude参数,或者在输出字符串时过滤掉它们,可以非常容易地删除它们。
// 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;
}