Laravel Eloquent 日期系列化
Laravel Eloquent 日期系列化成 json,默认系列化格式为:2023-03-08T08:16:02.000000Z
。
原因是 Laravel 模型基类的 serializeDate()
时间系列化方法调用 Carbon\Traits\Converter::toJSON()
方法,返回的是 ISO-8601
格式的日期。
引起问题的代码如下:
1 | // Illuminate\Database\Eloquent\Concerns\HasAttributes |
解决办法是在模型中覆盖 serializeDate
方法,返回 Carbon\Traits\Converter::toDateTimeString()
方法就可以。
如代码,推荐把 serializeDate
方法放到一个 trait
中,在模型类中再 use
该 trait
。
1 | namespace App\Models\traits; |
添加 casts ‘datetime:Y-m-d H:i:s’ 来解决这个问题是不正确的,因为这样格式化的是转换后的 iso 标准时间,我国时间会有8小时误差。我们用覆盖
serializeDate
方法的方式,不管是用utc
时间还是本地时间,都不会有问题。
首先你要先设置 Laravel 的时区,在config/app.php
中把timezone
设为PRC
或Asia/Shanghai
,默认是 UTC 时间。
更好的解决方案
如果你的系统100%是给国人用,用上面的方法是没问题的。如果老外也用,你的 Laravel 应该使用 UTC
时间,显示的时候再转换成本地时间。
用js格式化日期
后的返回UTC时间,前端用 JS 格式化日期
1 | new Date('2023-03-08T08:16:02.000000Z').toLocaleString() |
后端日期转换
如果你不是用前端显示js,而是在 blade 中使用模板视图,可通过前端获取客户端时差,用 cookie 传到服务器。
1 | <script> |
服务器端获取时差,再设置给 Carbon。
1 | $user->created_at->addHours($_COOKIE['tzo'])->rawFormat('Y-m-d H:i:s'); |
Laravel Eloquent 日期系列化
https://coderpan.com/php/laravel-eloquent-serialize-date.html