起因
laravel 10 的安全修复截止至 2025日2月4日,需要升级到 11 版本。

Laravel 11 常用的时间处理包进行了依赖升级,Carbon 2和3都支持,但是如果不在 compsoer.json 中指定依赖版本会默认依赖 Carbon 3 ,Carbon 2 和 3 做了极大的功能升级,会对升级造成日期相关的不兼容,咱们列举下 2个3 的不同。

差异
对象可变性
这个改动印象范围极大,很容易造成隐藏的BUG,Carbon 2 直接对原属性进行修复,复用需要把对象进行 copy 操作,而Carbon 3 操作后需要进行赋值,否者不会生效。
// Carbon 2:默认创建 可变对象
$date = Carbon::parse('2023-10-01');
$date->addDay(); // 直接修改原对象
echo $date; // 输出 2023-10-02
// Carbon 3:默认创建 不可变对象
$date = Carbon::parse('2023-10-01');
$newDate = $date->addDay(); // 返回新对象,原对象不变
echo $date; // 输出 2023-10-01
echo $newDate; // 输出 2023-10-02
// 若需要可变对象,需显式转换
$mutable = $date->toMutable();$mutable->addDay();
diffIn*函数
这个改动印象范围极大,返回类型直接进行了修改。
$after = Carbon::now()->addSeconds(2);
$before = Carbon::now();
var_dump($after->diffInSeconds($before));
// 这是: int(1) 在 Carbon 2
// 这是: double(-1.999508) 在 Carbon 3
// 在 Carbon 3 中,使用(int) $after->diffInSeconds($before, true)或 (int) abs($after->diffInSeconds($before))可以明确获取绝对值和截断值,因此结果与 v2 中的结果相同。
// Carbon 2
$diff = $date1->diffInMonths($date2, true); // 第三个参数 $absolute 控制是否返回绝对值
// Carbon 3
$diff = $date1->diffInMonths($date2); // 仅返回绝对值,移除了 $absolute 参数
严谨性校验
Carbon::now()->addSeconds("400");
// 在 Carbon 2 中可以正常运行
// 在 Carbon3 中会报错,Carbon\Carbon::rawAddUnit(): Argument #3 ($value) must be of type int|float, string given
// 由于使用 php artsian config:cache 会把配置中 int 类型的配置 转化为 string 从而触发报错
// 比如 tymon/jwt-auth 的 ttl 过期时间 需要修改配置的写法
'ttl' => (int) env('JWT_TTL', 3600),
时区处理
// Carbon 2:依赖系统时区
// 假设系统时区是 UTC
$date = Carbon::now(); // 时区为 UTC
// Carbon 3:默认使用 UTC,更明确
$date = Carbon::now(); // 时区为 UTC,而非系统时区
// 需显式指定本地时区
$localDate = Carbon::now('Asia/Shanghai');
本地化与格式
// Carbon 2:依赖 Symfony 翻译组件
Carbon::setLocale('zh_CN');
echo Carbon::now()->diffForHumans(); // 需要安装 symfony/translation
// Carbon 3:内置基础翻译,减少依赖
Carbon::setLocale('zh_CN');
echo Carbon::now()->diffForHumans(); // 无需额外依赖
实在不行
"nesbot/carbon": "^2.0",
对象可变性 / diffIn*函数 / 时区处理 这三个我本地测试和你的例子都不同 时区处理 那个用的是 php 自带的时区