2010-11-20 62 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; 
相關問題