Carbon(nesbot/carbon)– PHP 日期时间利器化

一、Carbon介绍

Carbon 是 PHP 中最流行的 日期时间处理库,基于 PHP 原生的 DateTime 类封装,提供 链式操作、易读 API、时区支持 等强大功能。

特点:

  • 链式调用,语义化强

  • 支持日期时间加减、比较、格式化

  • 支持中文等多语言友好显示

  • 可与 Laravel、Hyperf 等框架无缝集成

官方文档:https://carbon.nesbot.com/docs/

安装composer require nesbot/carbon

二、基本使用

2.1 获取当前时间

$now = Carbon::now(); // 当前时间,默认系统时区
echo $now; // 2023-09-28 15:30:12

// 指定时区:
$nowShanghai = Carbon::now('Asia/Shanghai');

2.2 日期创建

$dt1 = Carbon::create(2023, 9, 28, 15, 30, 0); // 年, 月, 日, 时, 分, 秒
$dt2 = Carbon::parse('2023-12-31 23:59:59');
$dt3 = Carbon::today(); // 当天 0:00:00
$dt4 = Carbon::tomorrow(); // 明天 0:00:00
$dt5 = Carbon::yesterday(); // 昨天 0:00:00

2.3 日期格式化

$now = Carbon::now();
echo $now->toDateString();    // 2023-09-28
echo $now->toTimeString();    // 15:30:12
echo $now->toDateTimeString();// 2023-09-28 15:30:12
echo $now->format('Y-m-d H:i'); // 自定义格式

2.4 日期加减操作

$dt = Carbon::now();

echo $dt->addDays(3);    // 当前时间 +3天
echo $dt->subHours(5);   // 当前时间 -5小时
echo $dt->addMonthsNoOverflow(1); // 避免月份溢出

2.5 日期比较

$dt1 = Carbon::parse('2023-09-28');
$dt2 = Carbon::parse('2023-10-01');

if ($dt1->lt($dt2)) {
    echo "dt1 小于 dt2";
}

echo $dt1->diffInDays($dt2); // 返回天数差
echo $dt1->diffForHumans($dt2); // 语义化描述: "3 days before"

2.6 时区转换

$dt = Carbon::now('UTC');
$dtShanghai = $dt->copy()->setTimezone('Asia/Shanghai');
echo $dtShanghai;

2.7 本地化输出

Carbon::setLocale('zh'); // 设置中文

$dt1 = Carbon::now();
$dt2 = Carbon::parse('2025-10-01');

echo $dt1->diffForHumans($dt2); // 输出: 3 天前 / 3 天后

2.8 链式操作

$dt = Carbon::now()->addDays(5)->subHours(3)->format('Y-m-d H:i:s');
echo $dt;

三、Carbon 高级使用技巧合集

3.1 时间区间判断

判断某个时间是否在区间内

use Carbon\Carbon;

$start = Carbon::parse('2023-09-01');
$end = Carbon::parse('2023-09-30');
$check = Carbon::parse('2023-09-15');

if ($check->between($start, $end)) {
    echo "时间在区间内";
}

between($start, $end, $equal = true)

  • $equal = true 表示包含边界值

判断时间是否已经过期

$expire = Carbon::parse('2023-09-30');
if (Carbon::now()->greaterThan($expire)) {
    echo "已过期";
}

3.2 排班和周期任务计算

每周一、三、五触发

$today = Carbon::now();
if (in_array($today->dayOfWeek, [1, 3, 5])) {
    echo "今天需要执行任务";
}

dayOfWeek 返回 0-6(周日 = 0,周一 = 1 … 周六 = 6)

获取下一个执行日期

$next = Carbon::now()->next(Carbon::WEDNESDAY); // 下一个周三
echo $next;

3.3 人性化日期显示

Carbon::setLocale('zh');

$dt1 = Carbon::parse('2025-09-25');
$dt2 = Carbon::now();

echo $dt1->diffForHumans($dt2); // "3 天前"
  • 适合前端展示时间差,如评论、日志等

3.4 日期加减与复合操作

$dt = Carbon::now()
    ->addDays(3)      // +3天
    ->subHours(5)     // -5小时
    ->addMinutes(30); // +30分钟

echo $dt->format('Y-m-d H:i:s');
  • 链式操作可显著提升代码可读性

3.5 与 MySQL 日期时间无缝转换

读取数据库 datetime

$createdAt = Carbon::parse($user->created_at);

写入数据库 datetime

$user->expire_at = Carbon::now()->addDays(7)->toDateTimeString();
$user->save();
  • toDateTimeString() 输出 Y-m-d H:i:s 格式,直接可存入 MySQL

3.6 时间戳转换与操作

$timestamp = 1750000000;

// 时间戳转 Carbon
$dt = Carbon::createFromTimestamp($timestamp);

// Carbon 转时间戳
echo $dt->timestamp;

3.7 本地化与时区

// 设置默认时区
Carbon::setLocale('zh');
$dt = Carbon::now('Asia/Shanghai');

// 转换到其他时区
$dtUtc = $dt->copy()->setTimezone('UTC');

3.8 计算时间差

$start = Carbon::parse('2025-09-01');
$end = Carbon::parse('2025-09-28');

echo $start->diffInDays($end);       // 相差天数
echo $start->diffInHours($end);      // 相差小时数
echo $start->diffInMinutes($end);    // 相差分钟数
  • diffForHumans() 输出语义化的时间差

3.9 生成时间区间数组(可用于报表)

$period = Carbon::parse('2025-09-01')->daysUntil('2025-09-07');
foreach ($period as $date) {
    echo $date->toDateString() . PHP_EOL;
}

四、高性能使用建议

  • 统一时区,避免跨时区混乱

  • 避免重复 parse,数据库时间尽量直接使用 Carbon 对象

  • 链式操作,提升可读性

  • 本地化,展示友好日期给用户

  • 结合缓存,复杂报表或大量时间计算可先缓存结果