我有两个表格日期:
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框架,但很多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
其他回答
我在下面的页面上找到了您的文章,其中包含了许多PHP日期时间计算的参考。
使用PHP计算两个日期(和时间)之间的差异。下一页提供了一系列不同的方法(共7种),用于使用PHP执行日期/时间计算,以确定两个日期之间的时间差(小时、弹药)、天、月或年。
请参阅PHP日期时间–计算两个日期之间差值的7种方法。
最好的做法是使用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);
我在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
您还可以使用以下代码通过向上舍入分数来返回日期差异$date1=$duedate;//指定到期日echo$date2=日期(“Y-m-d”);//当前日期$ts1=字符串时间($date1);$ts2=字符串时间($date2);$seconds_diff=$ts1-$ts2;echo$datediff=ceil(($seconds_diff/3600)/24);//天内返回
如果您使用php的floor方法而不是ceil,它将返回舍入分数。请检查此处的差异,有时,如果您的临时服务器时区与现场站点时区不同,在这种情况下,您可能会得到不同的结果,因此请相应地更改条件。
一便士一英镑:我刚刚回顾了几个解决方案,所有这些方案都使用floor()提供了一个复杂的解决方案,然后四舍五入到26年12个月零2天的解决方案中,原本应该是25年11个月零20天!!!!
这是我对这个问题的看法:可能不优雅,可能编码不好,但如果不计算LEAP年份,则提供了更接近答案的答案,显然闰年可以编码为,但在这种情况下-正如其他人所说,也许您可以提供以下答案:我已经包含了所有测试条件和print_r,以便您可以更清楚地看到结果的构造:在这里,
//设置输入日期/变量::
$ISOstartDate = "1987-06-22";
$ISOtodaysDate = "2013-06-22";
//我们需要将ISO yyyy-mm-dd格式分解为yyyy-mm-d格式,如下所示:
$yDate[]=爆炸('-',$ISOstartDate);print_r($yDate);
$zDate[]=爆炸('-',$ISOtodaysDate);print_r($zDate);
// Lets Sort of the Years!
// Lets Sort out the difference in YEARS between startDate and todaysDate ::
$years = $zDate[0][0] - $yDate[0][0];
// We need to collaborate if the month = month = 0, is before or after the Years Anniversary ie 11 months 22 days or 0 months 10 days...
if ($months == 0 and $zDate[0][1] > $ydate[0][1]) {
$years = $years -1;
}
// TEST result
echo "\nCurrent years => ".$years;
// Lets Sort out the difference in MONTHS between startDate and todaysDate ::
$months = $zDate[0][1] - $yDate[0][1];
// TEST result
echo "\nCurrent months => ".$months;
// Now how many DAYS has there been - this assumes that there is NO LEAP years, so the calculation is APPROXIMATE not 100%
// Lets cross reference the startDates Month = how many days are there in each month IF m-m = 0 which is a years anniversary
// We will use a switch to check the number of days between each month so we can calculate days before and after the years anniversary
switch ($yDate[0][1]){
case 01: $monthDays = '31'; break; // Jan
case 02: $monthDays = '28'; break; // Feb
case 03: $monthDays = '31'; break; // Mar
case 04: $monthDays = '30'; break; // Apr
case 05: $monthDays = '31'; break; // May
case 06: $monthDays = '30'; break; // Jun
case 07: $monthDays = '31'; break; // Jul
case 08: $monthDays = '31'; break; // Aug
case 09: $monthDays = '30'; break; // Sept
case 10: $monthDays = '31'; break; // Oct
case 11: $monthDays = '30'; break; // Nov
case 12: $monthDays = '31'; break; // Dec
};
// TEST return
echo "\nDays in start month ".$yDate[0][1]." => ".$monthDays;
// Lets correct the problem with 0 Months - is it 11 months + days, or 0 months +days???
$days = $zDate[0][2] - $yDate[0][2] +$monthDays;
echo "\nCurrent days => ".$days."\n";
// Lets now Correct the months to being either 11 or 0 Months, depending upon being + or - the years Anniversary date
// At the same time build in error correction for Anniversary dates not being 1yr 0m 31d... see if ($days == $monthDays )
if($days < $monthDays && $months == 0)
{
$months = 11; // If Before the years anniversary date
}
else {
$months = 0; // If After the years anniversary date
$years = $years+1; // Add +1 to year
$days = $days-$monthDays; // Need to correct days to how many days after anniversary date
};
// Day correction for Anniversary dates
if ($days == $monthDays ) // if todays date = the Anniversary DATE! set days to ZERO
{
$days = 0; // days set toZERO so 1 years 0 months 0 days
};
echo "\nTherefore, the number of years/ months/ days/ \nbetween start and todays date::\n\n";
printf("%d years, %d months, %d days\n", $years, $months, $days);
最终结果是:26年零个月零天
这就是我在2013年6月22日做生意的时间——哎呦!