Carbon 是 PHP 的日期时间处理类库,基于 DateTime 封装,提供可读、链式、时区友好的操作;避免手动写 date()、strtotime() 导致的逻辑错误,如“+1 month”跨月异常。

Carbon 是什么,为什么不用自己写日期逻辑
Carbon 不是“插件”,是 PHP 的一个日期时间处理类库,基于 DateTime 封装,让 date()、strtotime() 这些原始操作变得可读、链式、时区友好。你不需要它也能干活,但一旦涉及“上周一”“30天后是否周末”“UTC 转北京时间”这类需求,硬写容易出错、难测试、难维护。
常见错误现象:date('Y-m-d', strtotime('+1 month')) 在 1 月 31 日执行会变成 3 月 3 日(跳过 2 月),而 Carbon::now()->addMonth() 默认是“同日推进”,行为更可控。
用 composer require 安装 Carbon 的正确姿势
直接运行命令即可,无需额外配置或手动下载:
composer require nesbot/carbon
说明:nesbot/carbon 是官方包名,不是 carbon 或 carbonphp。旧项目若已锁死 PHP 版本(比如 PHP 7.2),可能需要指定兼容版本:
- PHP 8.0+:默认装最新版
v3.x(需use Carbon\Carbon;) - PHP 7.2–7.4:加版本约束,如
composer require nesbot/carbon:^2.60(仍用use Carbon\Carbon;,API 基本一致) - 如果报
Root composer.json requires nesbot/carbon ^3.0 -> found nesbot/carbon[v3.0.0, ..., v3.x] but these were not loaded,大概率是autoload没生效,先跑composer dump-autoload
在代码里怎么安全地用 Carbon(别踩 new DateTime() 的坑)
别再用 new DateTime() 或 date_default_timezone_set() 全局设时区了——Carbon 默认用系统时区,但推荐显式指定,避免部署环境差异导致时间偏移:
- 全局设置一次(如 Laravel 启动时):
Carbon::setTestNow(Carbon::now('Asia/Shanghai'));更推荐每次实例化时传时区:Carbon::now('Asia/Shanghai') - 解析字符串要小心:
Carbon::parse('2023-02-30')不报错,但会静默转成 2023-03-02;生产环境建议配合try/catch捕获Exception - 数据库存时间戳?用
$carbon->timestamp或$carbon->getTimestamp(),别用$carbon->format('U')——后者是字符串,易被当成普通文本拼进 SQL
Carbon v2 和 v3 的关键差异点(升级前必看)
v3 强制要求 PHP 8.0+,并移除了部分松散方法,升级不是简单换版本号:
-
Carbon::createFromDate()等静态构造函数在 v3 中已废弃,统一用Carbon::create()或Carbon::parse() - v3 默认关闭“相对时间字符串自动修正”,例如
Carbon::parse('next monday')在 v2 中可能返回本周一(如果今天就是周一),v3 严格按字面意思走“下一个周一” - 如果你用了
Carbon::setToStringFormat()全局格式化,v3 中该方法已删除,改用Carbon::serializeUsing(fn ($c) => $c->format('Y-m-d'))
真正麻烦的不是语法,是隐式行为变化——尤其在定时任务、报表生成这种依赖“某天零点”“当月第一天”的场景,建议升级前用真实业务数据跑一遍时间计算逻辑。









