优雅的方式来获得两个日期之间的月数?

Sim*_*mon 59 php date

假设我在变量中有两个日期,比如

$date1 = "2009-09-01";
$date2 = "2010-05-01";
Run Code Online (Sandbox Code Playgroud)

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

有没有办法通过使用日期函数来获取它,或者我必须爆炸我的字符串并进行一些计算?

非常感谢

Vin*_*ard 120

对于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)
Run Code Online (Sandbox Code Playgroud)

DateTime :: 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
Run Code Online (Sandbox Code Playgroud)

但它不是很精确(每月不总是30天).

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

编辑:如果你不能使用DateTime :: diff或你的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
Run Code Online (Sandbox Code Playgroud)

  • 如果你有两个相隔超过一年的日期,你会发现`var_dump($ d1-> diff($ d2) - > m)`你会在DateTime方法(这个答案中的前一个)中失败,因为它只显示几个月没有加起来的月份.试试看看会发生什么:`$ d1 = new DateTime("2011-05-14");``$ d2 = new DateTime("2013-02-02");``$ d3 = $ d1-> diff ($ d2);``echo'<pre>'.print_r($ d3,true).'</ pre>';` (7认同)

Chu*_*ess 34

或者,如果您想要程序样式:

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

更新:添加了一些代码来记录这些年.

  • 如果您的日期相隔一年以上,则此操作将失败。您需要在答案中加上年* 12才能得到月。 (2认同)

小智 20

或者简单的计算会给出:

$numberOfMonths = abs((date('Y', $endDate) - date('Y', $startDate))*12 + (date('m', $endDate) - date('m', $startDate)))+1;
Run Code Online (Sandbox Code Playgroud)

准确,适用于所有情况.


Val*_*spa 14

在测试了大量的解决方案后,将所有解决方案全部用于单元测试,这就是我提出的:

/**
 * 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);
}
Run Code Online (Sandbox Code Playgroud)

例如,它将返回(来自单元测试的测试用例):

  • 01.11.2013 - 30.11.2013 - 1个月
  • 01.01.2013 - 2013年12月31日 - 12个月
  • 2011年1月31日 - 2011年2月28日 - 1个月
  • 01.09.2009 - 01.05.2010 - 8个月
  • 01.01.2013 - 2013年3月31日 - 3个月
  • 15.02.2013 - 2013年4月15日 - 2个月
  • 01.02.1985 - 2013年12月31日 - 347个月

注意:由于它与日期的四舍五入,即使是半个月也会四舍五入,如果你在某些情况下使用它可能会导致问题.所以不要在这种情况下使用它,它会引起你的问题.

例如:

  • 02.11.2013 - 2013年12月31日将返回2,而不是1(如预期的那样).