PHP计算两个日期之间的完整月数

PHP计算两个日期之间的完整月数,php,date,datetime,diff,Php,Date,Datetime,Diff,我试图以月为单位计算两个日期之间的差值,但方法更为具体 例如,我有两个日期:2017-11-01和2018-01-31 因此,我需要3个月。也就是说,这两个日期之间有3个完整的计费月 下面是它的工作原理: 第1个月:2017-11-01至2017-11-30 第2个月:2017-12-01至2017-12-31 第3个月:2018-01-01至2018-01-31 我在DateTime类中尝试了diff方法,它产生了一些没有多大帮助的结果。这里有一个例子 <?php $date1 =

我试图以月为单位计算两个日期之间的差值,但方法更为具体

例如,我有两个日期:2017-11-012018-01-31 因此,我需要3个月。也就是说,这两个日期之间有3个完整的计费月

下面是它的工作原理:

  • 第1个月:2017-11-01至2017-11-30
  • 第2个月:2017-12-01至2017-12-31
  • 第3个月:2018-01-01至2018-01-31
我在DateTime类中尝试了diff方法,它产生了一些没有多大帮助的结果。这里有一个例子

<?php
$date1 = DateTime::createFromFormat('Y-m-d H:i:s', '2017-11-01 00:00:00');
$date2 = DateTime::createFromFormat('Y-m-d H:i:s', '2018-01-31 00:00:00');
$diff = $date1->diff($date2);
print_r($diff)

result:
DateInterval Object
(
    [y] => 0
    [m] => 2
    [d] => 30
    [h] => 0
    [i] => 0
    [s] => 0
    [weekday] => 0
    [weekday_behavior] => 0
    [first_last_day_of] => 0
    [invert] => 0
    [days] => 91
    [special_type] => 0
    [special_amount] => 0
    [have_weekday_relative] => 0
    [have_special_relative] => 0
)
这两个日期之间的差异应显示为2个月和30天,而不是3个月


如果您有任何帮助或想法,我们将不胜感激。

在进行比较之前,请在结束日期前再加上一天。如果原始结束日期是该月的最后一天,那么新的结束日期将滚动到下一个月,您将在diff对象中获得正确的“完整”月数。如果原始日期是某一天,但是该月的最后一天,则不会更改结果

$start = '2017-11-01';
$end = '2018-01-31';

$date1 = DateTime::createFromFormat('Y-m-d', $start);
$date2 = DateTime::createFromFormat('Y-m-d', $end)->add(new DateInterval('P1D'));

echo $date1->diff($date2)->m, "\n";

看来你在计算中损失了一天。因为您需要以月为单位的间隔,包括第一天/最后一天-然后您应该将这一天添加到间隔中

因此,这种情况下的解决方案是:

$date1 = DateTime::createFromFormat('Y-m-d H:i:s', '2017-11-01 00:00:00');
$date2 = DateTime::createFromFormat('Y-m-d H:i:s', '2018-01-31 23:59:59');
$diff = $date1->diff($date2);
或:

甚至:

$date1 = DateTime::createFromFormat('Y-m-d H:i:s', '2017-11-01 00:00:00');
$date2 = DateTime::createFromFormat('Y-m-d H:i:s', '2018-02-01 00:00:00');
$diff = $date1->diff($date2);
使用碳:

Carbon::parse('2017-10-31')->diffInMonths(Carbon::now());

@534F可能重复-这个问题是关于PHP的。你的链接是关于C#。可能重复的抱歉,错误的标签,第一次海报。哦,我在发帖前搜索了很多,但什么也没找到。它不是任何一个实例的重复,只是要小心包含小时,因为DST真的会一年两次把事情搞得一团糟……最后一天不包括在内,因为两个
DateTime
实例中的时间都是当前时间(因为没有指定),所以最后一天不太“计算”。如果他需要使用
$date2
,更好的解决方案是执行
$date1->setTime(0,0,0)$date2->setTime(0,0,1),而不是添加一天。这不会达到预期的结果。OP需要
$diff->m
在diff结果中计算一个完整的月份,如果该范围的最后一天是它所在月份的最后一天,则无论时间如何,
diff()
都不会这样做。
$date1 = DateTime::createFromFormat('Y-m-d H:i:s', '2017-11-01 00:00:00');
$date2 = DateTime::createFromFormat('Y-m-d H:i:s', '2018-02-01 00:00:00');
$diff = $date1->diff($date2);
Carbon::parse('2017-10-31')->diffInMonths(Carbon::now());