不使用PHP 5.3的date_diff函数(我使用的是PHP 5.2.17),有没有一种简单而准确的方法呢?我正在考虑类似下面的代码,但我不知道如何解释闰年:
$days = ceil(abs( strtotime('2000-01-25') - strtotime('2010-02-20') ) / 86400);
$months = ???;
我正在努力计算出一个人的月数。
答案 0 :(得分:75)
$date1 = '2000-01-25';
$date2 = '2010-02-20';
$ts1 = strtotime($date1);
$ts2 = strtotime($date2);
$year1 = date('Y', $ts1);
$year2 = date('Y', $ts2);
$month1 = date('m', $ts1);
$month2 = date('m', $ts2);
$diff = (($year2 - $year1) * 12) + ($month2 - $month1);
您可能也希望将日期包含在某处,具体取决于您是否表示整个月份。希望你能得到这个想法。
答案 1 :(得分:14)
这是我在课堂上写的一个简单方法,用于计算两个特定日期所涉及的月数:
public function nb_mois($date1, $date2)
{
$begin = new DateTime( $date1 );
$end = new DateTime( $date2 );
$end = $end->modify( '+1 month' );
$interval = DateInterval::createFromDateString('1 month');
$period = new DatePeriod($begin, $interval, $end);
$counter = 0;
foreach($period as $dt) {
$counter++;
}
return $counter;
}
答案 2 :(得分:2)
像这样:
$date1 = strtotime('2000-01-25');
$date2 = strtotime('2010-02-20');
$months = 0;
while (($date1 = strtotime('+1 MONTH', $date1)) <= $date2)
$months++;
echo $months;
如果您想要包含天数,请使用以下内容:
$date1 = strtotime('2000-01-25');
$date2 = strtotime('2010-02-20');
$months = 0;
while (strtotime('+1 MONTH', $date1) < $date2) {
$months++;
$date1 = strtotime('+1 MONTH', $date1);
}
echo $months, ' month, ', ($date2 - $date1) / (60*60*24), ' days'; // 120 month, 26 days
答案 3 :(得分:1)
我最近需要计算从产前到5岁(60个月以上)的月龄。
上述两个答案都不适合我。 我试过的第一个,基本上是一个代替deceze的答案
$bdate = strtotime('2011-11-04');
$edate = strtotime('2011-12-03');
$age = ((date('Y',$edate) - date('Y',$bdate)) * 12) + (date('m',$edate) - date('m',$bdate));
. . .
这与设置日期失败,显然答案应为0,因为尚未达到月份标记(2011-12-04),代码如何返回1。
我尝试的第二种方法,使用Adam的代码
$bdate = strtotime('2011-01-03');
$edate = strtotime('2011-02-03');
$age = 0;
while (strtotime('+1 MONTH', $bdate) < $edate) {
$age++;
$bdate = strtotime('+1 MONTH', $bdate);
}
. . .
失败并说0个月,应该是1。
对我有用的是这段代码的一点扩展。我使用的是以下内容:
$bdate = strtotime('2011-11-04');
$edate = strtotime('2012-01-04');
$age = 0;
if($edate < $bdate) {
//prenatal
$age = -1;
} else {
//born, count months.
while($bdate < $edate) {
$age++;
$bdate = strtotime('+1 MONTH', $bdate);
if ($bdate > $edate) {
$age--;
}
}
}
答案 4 :(得分:0)
跟进@deceze的答案(我对他的答案赞不绝口)。即使第一个日期的天没有达到第二个日期的那一天,月份仍将作为一个整体计算。
这是关于包括当天的简单解决方案:
$ts1=strtotime($date1);
$ts2=strtotime($date2);
$year1 = date('Y', $ts1);
$year2 = date('Y', $ts2);
$month1 = date('m', $ts1);
$month2 = date('m', $ts2);
$day1 = date('d', $ts1); /* I'VE ADDED THE DAY VARIABLE OF DATE1 AND DATE2 */
$day2 = date('d', $ts2);
$diff = (($year2 - $year1) * 12) + ($month2 - $month1);
/* IF THE DAY2 IS LESS THAN DAY1, IT WILL LESSEN THE $diff VALUE BY ONE */
if($day2<$day1){ $diff=$diff-1; }
逻辑是,如果第二个日期的日期小于第一个日期的日期,它会将$diff
变量的值减一。
答案 5 :(得分:0)
这个怎么样:
$d1 = new DateTime("2009-09-01");
$d2 = new DateTime("2010-09-01");
$months = 0;
$d1->add(new \DateInterval('P1M'));
while ($d1 <= $d2){
$months ++;
$d1->add(new \DateInterval('P1M'));
}
print_r($months);
答案 6 :(得分:0)
这是我的解决方案。它只检查年份和日期。所以,如果一个日期是&#39; 31.10.15&#39;和其他是&#39; 02.11.15&#39;它返回1个月。
function get_interval_in_month($from, $to) {
$month_in_year = 12;
$date_from = getdate(strtotime($from));
$date_to = getdate(strtotime($to));
return ($date_to['year'] - $date_from['year']) * $month_in_year -
($month_in_year - $date_to['mon']) +
($month_in_year - $date_from['mon']);
}
答案 7 :(得分:0)
$date1 = '2000-01-25';
$date2 = '2010-02-20';
$ts1 = strtotime($date1);
$ts2 = strtotime($date2);
$year1 = date('Y', $ts1);
$year2 = date('Y', $ts2);
$month1 = date('m', $ts1);
$month2 = date('m', $ts2);
$diff = (($year2 - $year1) * 12) + ($month2 - $month1);
如果上述月份从1月切换为2月,则返回$ diff = 1 但是,如果您只想在30天后考虑下个月,则在下面的代码行和上面添加代码。
$day1 = date('d', $ts1);
$day2 = date('d', $ts2);
if($day2 < $day1){ $diff = $diff - 1; }
答案 8 :(得分:0)
这是我的解决方案。它会检查日期的年份和月份并找出差异。
$date1 = '2000-01-25';
$date2 = '2010-02-20';
$d1=new DateTime($date2);
$d2=new DateTime($date1);
$Months = $d2->diff($d1);
$howeverManyMonths = (($Months->y) * 12) + ($Months->m);
答案 9 :(得分:0)
要计算两个日期之间的日历月数(也问here),通常我会做这样的事情。我将两个日期转换为字符串,例如“ 2020-05”和“ 1994-05”,然后从下面的函数中获取它们各自的结果,然后对这些结果进行减法运算。
/**
* Will return number of months. For 2020 April, that will be the result of (2020*12+4) = 24244
* 2020-12 = 24240 + 12 = 24252
* 2021-01 = 24252 + 01 = 24253
* @param string $year_month Should be "year-month", like "2020-04" etc.
*/
static private function calculate_month_total($year_month)
{
$parts = explode('-', $year_month);
$year = (int)$parts[0];
$month = (int)$parts[1];
return $year * 12 + $month;
}
答案 10 :(得分:0)
这就是我最终解决它的方式。我知道我来晚了,但我希望这可以节省一些人的时间和代码行。
我使用DateInterval :: format以年,月和日显示人类可读的倒计时时钟。
在https://www.php.net/manual/en/dateinterval.format.php中查看格式表,以查看有关如何修改返回值的选项。应该给您您想要的东西。
$origin = new DateTime('2020-10-01');
$target = new DateTime('2020-12-25');
$interval = $origin->diff($target);
echo $interval->format('%y years, %m month, %d days until Christmas.');
产出:0年,2个月,24天
答案 11 :(得分:0)
我的解决方案是几个答案的混合。我不想做一个循环,尤其是当我在 $interval->diff 中有所有数据时,我只是做了数学计算,如果在我的情况下,月数可能是负数,所以这是我的方法。
/**
* Function will give you the difference months between two dates
*
* @param string $start_date
* @param string $end_date
* @return int|null
*/
public function get_months_between_dates(string $start_date, string $end_date): ?int
{
$startDate = $start_date instanceof Datetime ? $start_date : new DateTime($start_date);
$endDate = $end_date instanceof Datetime ? $end_date : new DateTime($end_date);
$interval = $startDate->diff($endDate);
$months = ($interval->y * 12) + $interval->m;
return $startDate > $endDate ? -$months : $months;
}
答案 12 :(得分:0)
function date_duration($date){
$date1 = new DateTime($date);
$date2 = new DateTime();
$interval = $date1->diff($date2);
if($interval->y > 0 and $interval->y < 2){
return $interval->y.' year ago';
}else if($interval->y > 1){
return $interval->y.' years ago';
}else if($interval->m > 0 and $interval->m < 2){
return $interval->m.' month ago';
}else if($interval->m > 1){
return $interval->y.' months ago';
}else if($interval->d > 1){
return $interval->d.' days ago';
}else{
if($interval->h > 0 and $interval->h < 2){
return $interval->h.' hour ago';
}else if($interval->h > 1){
return $interval->h.' hours ago';
}else{
if($interval->i > 0 and $interval->i < 2){
return $interval->i.' minute ago';
}else if($interval->i > 1){
return $interval->i.' minutes ago';
}else{
return 'Just now';
}
}
}
}
返回 11 个月前、2 年前、5 分钟前的日期区分样式
示例:
echo date_duration('2021-02-28 14:59:00.00');
将根据您当前的月份返回“1 个月前”