You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel将timestamp转为date:Y/n/j格式时显示错误如何解决

Laravel日期cast格式转换偏差问题解答

问题原因

Laravel 7+ 版本默认对日期字段做JSON序列化时,会统一转换为UTC时区输出,不受config/app.php中timezone配置的影响。你配置的date:Y/n/j格式转换是在序列化阶段执行的,因此会基于转换后的UTC时间做日期格式化:

  • 你数据库中存储的2021-06-08 01:00:01为东九区(Asia/Tokyo)时间,转换为UTC时间后为2021-06-07 16:00:01,格式化日期就得到2021/6/7
  • 当存储的时间大于等于东九区2021-06-08 09:00:00时,转换为UTC时间后为2021-06-08 00:00:00,格式化日期就得到预期的2021/6/8,和你观察到的现象完全吻合。

解决方案

方案1:全局配置序列化使用应用时区(推荐)

Laravel 8.49.0及以上版本可直接在.env文件中添加以下配置,让日期序列化自动使用你配置的Asia/Tokyo时区:

SERIALIZE_DATES_USING_TIMEZONE=true

配置完成后执行php artisan config:cache清除配置缓存即可生效。
如果你的Laravel 8小版本低于8.49.0,可在app/Providers/AppServiceProvider.php的boot方法中添加以下代码实现相同效果:

use Illuminate\Support\Carbon;

public function boot()
{
    Carbon::serializeUsing(function ($carbon) {
        return $carbon->toIso8601String();
    });
}

方案2:单独调整该字段的转换逻辑

如果不想修改全局序列化规则,只需要调整created_at字段的输出格式,可以将模型中的casts配置替换为自定义访问器:

class Diary extends Model
{
    // 移除原有created_at的casts配置
    public function getCreatedAtAttribute($value)
    {
        return \Carbon\Carbon::parse($value)->timezone(config('app.timezone'))->format('Y/n/j');
    }
}

可选补充:对齐数据库连接时区

为了避免后续读写时间出现其他时区偏差,建议在config/database.php的MySQL配置项中添加时区配置,和应用时区保持一致:

'mysql' => [
    // 其他原有配置保持不变
    'timezone' => '+09:00',
],

内容的提问来源于stack exchange,提问作者Ricardinho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.15 13:54:02