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

Laravel升级至8.0后timestamp时间戳存储日期格式错误问题

问题根因

这个问题和PHP时区配置没有关系,核心是两个逻辑错误:

  • 你之前写的按操作系统分支返回日期格式的getDateFormat()逻辑本身不成立:SQL Server的日期解析规则和PHP运行在Windows还是Linux没有绑定关系,旧版Laravel 5.7下这套逻辑能跑,是因为当时框架对SQL Server驱动的日期格式化没有做毫秒精度适配,升级到Laravel 8之后,框架调整了Eloquent时间戳双向序列化的优先级,会完全使用getDateFormat()返回的格式做写入数据库转字符串和读取数据转时间对象两个操作,Windows分支返回的Y-d-m H:i:s.v本身就是日、月顺序颠倒的格式,写入时自然会把月和日存反。
  • 你尝试把全环境格式统一成Y-d-m H:i:s.v的做法,相当于让框架读取数据时也按日月颠倒的格式解析时间,后续用strtotime()、date()处理字符串时自然会出现展示错位。
解决方案

不要通过判断操作系统返回不同日期格式,按以下步骤配置即可同时兼容存储、读取、全场景展示:

1. 统一模型日期格式

删除所有SQL Server相关模型里原有按系统判断的getDateFormat()逻辑,替换为固定的标准格式:

public function getDateFormat()
{
    // 标准年-月-日顺序,兼容SQL Server datetime/datetime2类型的3位毫秒精度
    return 'Y-m-d H:i:s.v';
}

注意:格式必须保持Y-m-d的年-月-日顺序,不能写为Y-d-m,否则框架读取数据库值反序列化时间对象时就会出现日月错位。如果你的SQL Server版本低于2008、不支持毫秒精度,直接把格式改为Y-m-d H:i:s即可。

2. 配置PDO连接强制日期格式

打开config/database.php,找到对应SQL Server的连接配置项(驱动为sqlsrv),在options参数中添加强制日期格式配置,避免PDO驱动自动转换日期导致的顺序错位:

'connections' => [
    'sqlsrv' => [
        // 保留原有driver、host、database、username、password等配置不动
        'options' => [
            PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8,
            // 强制连接全程使用ISO标准年-月-日顺序解析日期
            PDO::SQLSRV_ATTR_DATETIME_FORMAT => "Y-m-d H:i:s.v",
        ],
    ],
],

配置完成后执行php artisan config:clear清除配置缓存。

3. 优化模板层时间格式化逻辑

不要用原生date()+strtotime()的组合处理Eloquent时间字段:Laravel默认会把created_at、updated_at字段转为Carbon时间实例,直接调用Carbon自带的format()方法做格式化即可,完全不会出现解析错位:

// 替换原有模板里的date+strtotime写法
<p>updated at: {{ $model->updated_at->format('d/m/Y H:i:s') }}</p>

Carbon内部是按时间戳数值存储时间的,只要模型读取时解析正确,不管怎么格式化都不会出现日月反转的问题。

验证方法

改完后做两步校验即可确认修复生效:

  • 新建一条测试模型数据,直接在SQL Server中查询对应字段值,确认存储的日期日月顺序正确
  • 取出该条测试数据,输出格式化后的时间字段,确认展示顺序符合预期

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 19:18:41