Laravel 大V Povilas Korop(@PovilasKorop)分享了一条超级实用的 Tip:
“Did you know
CarbonPeriodcan generate every date in a range? No more missing days in your charts.”

CarbonPeriod::create(now()->subdays(29), now());
就这么一行,瞬间唤起了我的痛苦记忆……
这让我想起曾经吃过的苦,相信很多人也有过类似的经历:做报表、仪表盘、排班表、日历的时候,最头疼的就是数据不连续:某天没订单、某天没人预约,图表上就会出现断档,看起来很丑、分析也很麻烦。

为什么呢?
因为在 PHP 里,手动处理日期区间简直是走“雷区”:
- 今天 31 号,减一个月直接变成 3 月 3 号?
- 跨年、跨闰年、夏令时切换,一不小心就少一天或多一天
- 用 strtotime() + for 循环写出来的代码,又丑又容易出 bug
- 做报表时最怕“某天突然没数据”,图表出现断档,领导一看就皱眉头
而 CarbonPeriod 正是专门解决痛点问题的利器,所以今天顺手分享给大家,以免还有人不知道而上当受罪。
什么是 CarbonPeriod?
CarbonPeriod 是 Laravel 自带的 Carbon 库提供的日期区间生成器。它可以按照你指定的起始日期、结束日期、间隔,生成一个完整的 Carbon 实例集合(可迭代)。
当然,CarbonPeriod 不限于仅在 Laravel 框架中使用。它是一个独立的 PHP 包,任何 PHP 项目都可以安装并使用。
CarbonPeriod 可以按照你指定的起始日期、结束日期和间隔,生成一个完整、连续、可迭代的 Carbon 实例集合,干净、优雅、少坑。
最简单用法:
use Carbon\CarbonPeriod;
$period = CarbonPeriod::create('2026-03-01', '2026-03-31'); // 默认每天
foreach ($period as $date) {
echo $date->format('Y-m-d') . PHP_EOL;
}
支持自定义间隔、过滤、排除首尾等,功能非常强大。
CarbonPeriod 的 7 个实战妙用(强烈推荐收藏)
以下是社区和实际项目中最常用、最好用的场景,附完整代码示例:
1. 报表/图表补全日期(最经典用法)
没有数据的日期也显示出来(零值填充):
$period = CarbonPeriod::create($startDate, $endDate);
// 或 CarbonPeriod::since($startDate)->until($endDate);
$dailyData = YourModel::whereBetween('date', [$startDate, $endDate])
->groupBy('date')
->get()
->pluck('value', 'date');
$chartData = $period->map(fn($date) => [
'date' => $date->format('Y-m-d'),
'value' => $dailyData[$date->format('Y-m-d')] ?? 0,
]);
2. 生成工作日历(只保留周一~周五)
$period = CarbonPeriod::create($start, $end)
->filter(fn($date) => $date->isWeekday());
$workingDays = $period->map(fn($date) => $date->format('Y-m-d'));
3. 生成每小时/每15分钟的时间槽(预约系统神器)
$period = CarbonPeriod::create('09:00', '18:00', '30 minutes');
$slots = $period->map(fn($time) => $time->format('H:i'));
4. 生成每周/每月汇总维度(报表分组)
// 每周
$period = CarbonPeriod::create($start, $end, '1 week');
// 每月
$period = CarbonPeriod::create($start, $end, '1 month');
5. 生成特定星期几的日期列表(比如只周一的会议)
$period = CarbonPeriod::create($start, $end)
->filter(fn($date) => $date->isMonday());
6. 生成测试数据 / 假数据(超级好用)
$fakeDates = CarbonPeriod::create(now()->subDays(30), now())
->map(fn($date) => [
'date' => $date->format('Y-m-d'),
'value' => rand(10, 100),
]);
7. 日历组件数据源(全月/全年的日期网格)
$monthPeriod = CarbonPeriod::create(
now()->startOfMonth(),
now()->endOfMonth()
);
进阶小技巧
- 支持流式写法:CarbonPeriod::since(‘2026-03-01’)->until(‘2026-03-31’)
- 支持无限周期:CarbonPeriod::create(‘now’, ‘1 day’, INF)
- 推荐使用 CarbonPeriodImmutable 不可变,以避免意外修改
- 高级方法:overlaps()、contains()、follows() 等,可判断两个时间段的关系
- 排除首尾日期:
->excludeStartDate()/->excludeEndDate() - 自定义间隔:
'1 week'、'15 minutes'、'2 days' - 结合 Eloquent:先用 CarbonPeriod 生成完整日期,再 left join 数据表,实现零值填充
- 性能:CarbonPeriod 是迭代器,内存占用极低,适合大范围日期
总结
CarbonPeriod 是 Laravel 里一个被严重低估的工具。它真正强大的地方在于:让你用最少的代码,生成最完整、最干净的日期序列。
尤其是做报表、仪表盘、排班、预约、日历这类功能时,几乎是必备神器。
感谢 Povilas Korop 分享这个 Tip!
如果你也有关于 CarbonPeriod 的奇淫巧用,欢迎在评论区分享给大家~
完整文档: https://carbon.nesbot.com/guide/specialized-use/carbon-period.html