如何自定义Laravel Carbon DiffForHumans的年/月/日输出格式?
自定义日期差格式(单复数正确)
需求
需要生成符合以下格式的日期差文本,确保年、月、日的单复数形式正确:
- 13 Years, 1 Month, 10 Days
- 01 Year, 11 Months, 01 Day
尝试过的方法
方法1:使用Carbon的diffForHumans
$date = Carbon::parse('2010-08-29'); $formattedDate = $date->diffForHumans(['parts' => 3, 'join' => ', ']);
输出:13 years, 1 month, 4 weeks ago
问题:出现非需求的“weeks”单位,不符合年/月/日的格式要求。
方法2:使用diff()配合format()
$date = Carbon::parse('2010-08-29'); $formattedDate = $date->diff(now())->format('%y Year, %m Months and %d Days');
输出:13 Year, 1 Months and 28 Days
问题:单复数逻辑错误(数值为1时仍使用复数形式)。
方法3:带括号的备选格式
$date = Carbon::parse('2010-08-29'); $formattedDate = $date->diff(now())->format('%y Year(s), %m Month(s) and %d Day(s)');
输出:13 Year(s), 1 Month(s) and 28 Day(s)
问题:格式不符合要求,不需要括号包裹单复数标记。
可行解决方案
自定义处理函数,手动判断单复数并拼接文本:
public function customDiffForHumans(Carbon $date) : string{ $diff = $date->diff(now()); $years = $diff->y ? $diff->y . ' Year' . ($diff->y > 1 ? 's' : '') : '0 Years'; $months = $diff->m ? $diff->m . ' Month' . ($diff->m > 1 ? 's' : '') : '0 Months'; $days = $diff->d ? $diff->d . ' Day' . ($diff->d > 1 ? 's' : '') : '0 Days'; return implode(', ', array_filter([$years, $months, $days])); }
注:如果需要补零格式(如01 Year),可对数字部分使用str_pad($diff->y, 2, '0', STR_PAD_LEFT)处理。
原生PHP实现
原生PHP可通过DateInterval类实现类似功能,核心逻辑与上述自定义函数一致:
- 用
DateTime类计算日期差得到DateInterval对象 - 提取年、月、日属性,判断单复数后拼接文本
示例代码:
function customDateDiff(DateTime $date) : string { $diff = $date->diff(new DateTime()); $years = $diff->y ? str_pad($diff->y, 2, '0', STR_PAD_LEFT) . ' Year' . ($diff->y > 1 ? 's' : '') : '00 Years'; $months = $diff->m ? str_pad($diff->m, 2, '0', STR_PAD_LEFT) . ' Month' . ($diff->m > 1 ? 's' : '') : '00 Months'; $days = $diff->d ? str_pad($diff->d, 2, '0', STR_PAD_LEFT) . ' Day' . ($diff->d > 1 ? 's' : '') : '00 Days'; return implode(', ', [$years, $months, $days]); }
内容的提问来源于stack exchange,提问作者RG Servers
相关产品推荐
相关产品推荐

