2010-11-20 38 views
45

假设我有两个日期的变量,如优雅的方式来获得两个日期之间的月数?

$date1 = "2009-09-01"; 
$date2 = "2010-05-01"; 

我需要得到$date2$date1$date2 >= $date1)之间的月数。即我需要得到8

有没有办法通过使用date函数得到它,或者我必须爆炸我的字符串并做一些计算?

感谢很多

回答

93

对于PHP> = 5.3

$d1 = new DateTime("2009-09-01"); 
$d2 = new DateTime("2010-05-01"); 

var_dump($d1->diff($d2)->m); // int(4) 
var_dump($d1->diff($d2)->m + ($d1->diff($d2)->y*12)); // int(8) 

日期时间:: DIFF返回DateInterval对象

如果你不使用PHP 5.3或更高版本上运行,我想你”将不得不使用unix时间戳:

$d1 = "2009-09-01"; 
$d2 = "2010-05-01"; 

echo (int)abs((strtotime($d1) - strtotime($d2))/(60*60*24*30)); // 8 

但它不是很精确(没有每月总是30天)。

最后一件事:如果这些日期来自您的数据库,那么使用您的DBMS来完成这项工作,而不是PHP。

编辑:此代码应该更加确切,如果你不能使用日期时间::差异或您的RDBMS:

$d1 = strtotime("2009-09-01"); 
$d2 = strtotime("2010-05-01"); 
$min_date = min($d1, $d2); 
$max_date = max($d1, $d2); 
$i = 0; 

while (($min_date = strtotime("+1 MONTH", $min_date)) <= $max_date) { 
    $i++; 
} 
echo $i; // 8 
+0

在while循环的最佳解决方案!非常简洁和准确。做得好! +1 – 2010-11-20 16:40:24

+5

如果你有两个相隔一年以上的日期,你会发现var_dump($ d1-> diff($ d2) - > m)'会使你在DateTime方法中失败(这个答案中的第一个),因为它只会显示不合数年的月份。试试看看会发生什么: '$ d1 = new DateTime(“2011-05-14”);' '$ d2 = new DateTime(“2013-02-02”);' '$ d3 = $ d1 - > diff($ d2);' 'echo'

'.print_r($d3,true).'
';' – pathfinder 2013-03-30 05:56:51

+0

好吧,没有那么快......依靠strtotime可以让你头疼。 2011年1月31日至2011年2月28日之间有多少月? – 2013-06-13 08:16:15

23

或者,如果你想要的程序风格:

$date1 = new DateTime("2009-09-01"); 
$date2 = new DateTime("2010-05-01"); 
$interval = date_diff($date1, $date2); 
echo $interval->m + ($interval->y * 12) . ' months'; 

更新:增加了一些代码帐户多年。

+1

如果你的日期相隔一年多,这将会失败。您需要将年份* 12添加到您的答案才能获得月份。 – pathfinder 2013-03-30 06:01:31

+1

正确的是你。已更新以说明可能的年份。 – 2013-04-01 02:20:33

1

使用日期时间,这会给你几个月的任何量更准确的解决方案:

$d1 = new DateTime("2011-05-14"); 
$d2 = new DateTime(); 
$d3 = $d1->diff($d2); 
$d4 = ($d3->y*12)+$d3->m; 
echo $d4; 

你仍然需要处理剩下的日子$d3->d如果你的现实世界的问题不是那么简单和切这两个日期都是在这个月的第一个月的原始问题。

13

或者一个简单的计算将使:

$numberOfMonths = abs((date('Y', $endDate) - date('Y', $startDate))*12 + (date('m', $endDate) - date('m', $startDate)))+1; 

准确,适用于所有情况。

+0

这很好,除了它总是1。最后删除“+1”! :D – supercoolville 2015-08-02 20:16:07

11

测试吨的解决方案,把所有的单元测试之后,这是我拿出:

/** 
* Calculate the difference in months between two dates (v1/18.11.2013) 
* 
* @param \DateTime $date1 
* @param \DateTime $date2 
* @return int 
*/ 
public static function diffInMonths(\DateTime $date1, \DateTime $date2) 
{ 
    $diff = $date1->diff($date2); 

    $months = $diff->y * 12 + $diff->m + $diff->d/30; 

    return (int) round($months); 
} 

例如,它会(从单元测试的测试用例)返回:

  • 2013年11月1日 - 2013年11月30日 - 1个月
  • 2013年1月1日 - 2013年12月31日 - 12个月
  • 2011年1月31日 - 28.02。2011 - 1个月
  • 01.09.2009 - 01.05.2010 - 8个月
  • 2013年1月1日 - 2013年3月31日 - 3个月
  • 2013年2月15日 - 2013年4月15日 - 2个月
  • 1985年2月1日 - 2013年12月31日 - 347个月

注意:由于四舍五入它与天,甚至一个月的一半将被四舍五入,这可能会导致问题,如果你有一些情况下使用它。所以不要在这种情况下使用它,它会导致你的问题。

例如:

  • 2013年2月11日 - 2013年12月31日将返回图2,不为1(如预期)。
+1

该解决方案适用于以下几个月之间的“人类可读”月数:它返回人们期望看到的数据。在这种情况下,上面提到的四舍五入实际上是有帮助的,如果你不这样做,你会得到用户的“问题”! – Steve 2015-07-31 02:33:07

+0

31.01.2011 - 01.03.2011 - 1个月==>应该是2个月 – manish1706 2017-04-25 13:15:54

1

这是一个简单的方法,我在我的课写了数涉及到两个给定日期的月数:

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; 
} 
+0

虽然我给它+1,因为这是最接近给出任何实际结果。它仍然不完整,因为它会在同一个月的日期失败。 – 2016-12-21 20:50:42

3

我用这个:

$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); 
3

这是另一种方式得到两个日期之间的月数:

// Set dates 
$dateIni = '2014-07-01'; 
$dateFin = '2016-07-01'; 

// Get year and month of initial date (From) 
$yearIni = date("Y", strtotime($dateIni)); 
$monthIni = date("m", strtotime($dateIni)); 

// Get year an month of finish date (To) 
$yearFin = date("Y", strtotime($dateFin)); 
$monthFin = date("m", strtotime($dateFin)); 

// Checking if both dates are some year 

if ($yearIni == $yearFin) { 
    $numberOfMonths = ($monthFin-$monthIni) + 1; 
} else { 
    $numberOfMonths = ((($yearFin - $yearIni) * 12) - $monthIni) + 1 + $monthFin; 
} 
+0

这应该是正确的答案:) – 2016-12-21 21:38:41

0

我用这一点,在所有条件下工作

$fiscal_year = mysql_fetch_row(mysql_query("SELECT begin,end,closed FROM fiscal_year WHERE id = '2'")); 


      $date1 = $fiscal_year['begin']; 
      $date2 = $fiscal_year['end']; 

      $ts1 = strtotime($date1); 
      $ts2 = strtotime($date2); 


      $te=date('m',$ts2-$ts1); 

      echo $te; 
相关问题