使用Carbon计算两个日期的月份差结果为0,原因何在?
Carbon计算月份差返回0的原因及解决办法
问题原因
Carbon的diffInMonths方法默认按完整日历月数统计,并非依据总天数是否超过30/31天判断。它的核心逻辑是:仅当后一个日期是前一个日期的「对应日及以后」时,才会算作一个完整月。
以你的代码为例:
$d1 = new Carbon('2023-01-29'); $d2 = new Carbon('2023-02-28'); var_dump($d1->diffInMonths($d2)); // 输出int(0)
2023年2月没有29日,$d2(2月28日)并未达到$d1(1月29日)的「对应日」(理论上的2月29日),因此不满足一个完整日历月的条件,返回0。
解决办法
根据需求选择不同计算方式:
1. 按实际时长折算月份
如果想按总天数近似月份差(比如每月按30天计算),直接用天数差除以30即可:
$d1 = new Carbon('2023-01-29'); $d2 = new Carbon('2023-02-28'); $monthDiff = $d1->diffInDays($d2) / 30; var_dump($monthDiff); // 输出float(1.0333333333333)
2. 让Carbon按四舍五入统计月份差
使用diffInMonths的第三个精度参数,设置为CarbonInterface::DIFF_ROUND,会根据实际时长四舍五入返回结果:
use Carbon\CarbonInterface; $d1 = new Carbon('2023-01-29'); $d2 = new Carbon('2023-02-28'); var_dump($d1->diffInMonths($d2, true, CarbonInterface::DIFF_ROUND)); // 输出int(1)
3. 按「是否超过一个月时长」判断
直接通过天数差判断是否达到30天:
$d1 = new Carbon('2023-01-29'); $d2 = new Carbon('2023-02-28'); $isOverOneMonth = $d1->diffInDays($d2) >= 30; var_dump($isOverOneMonth); // 输出bool(true)
内容的提问来源于stack exchange,提问作者user3212439
相关产品推荐
相关产品推荐

