Laravel使用Unix时间戳填充模型时出现日期格式错误
问题原因与解决方案
这个问题我之前也碰到过,核心原因是你的Laravel模型设置和MySQL数据库列类型不匹配导致的,咱们一步步拆解:
为什么会报错?
你在模型里设置了protected $dateFormat = 'U';,这是告诉Laravel要把日期字段以**Unix时间戳(数字格式,比如1526321484)**的形式存入数据库,但你的created_at、updated_at列类型应该是datetime或timestamp——而MySQL 5.6的这两种列类型只接受标准的日期时间字符串(比如2024-05-20 14:30:00),直接传入数字时间戳就会触发Invalid datetime format错误。
解决方法
根据你的需求,有两种常用的处理方式:
方式一:修改数据库列类型为整数(推荐,适合确实需要存储Unix时间戳的场景)
如果你的目标就是把日期存成Unix时间戳,那需要把数据库里的created_at和updated_at列类型改成bigint(推荐用bigint避免2038年的int溢出问题):
- 如果你用Laravel迁移,可以写这样的代码:
// 新建迁移或者修改现有迁移 Schema::table('your_table_name', function (Blueprint $table) { $table->bigInteger('created_at')->change(); $table->bigInteger('updated_at')->change(); });
- 执行迁移后,模型里的
protected $dateFormat = 'U';就能正常工作了:Laravel会自动把Carbon日期对象转成Unix时间戳数字存入数据库,读取时也会自动转成Carbon实例供你使用。
方式二:保持数据库列类型,移除模型的dateFormat设置
如果不需要存储Unix时间戳,只是业务中需要用到时间戳,那完全没必要修改存储格式:
- 删掉模型里的
protected $dateFormat = 'U';,Laravel会自动处理datetime/timestamp列和Carbon对象的转换。 - 当你需要获取Unix时间戳时,直接通过Carbon实例的
timestamp属性即可:
// 获取created_at的Unix时间戳 $timestamp = $yourModel->created_at->timestamp;
这种方式更符合MySQL的设计规范,也能避免不必要的类型转换问题。
方式三:用访问器/修改器手动转换(不推荐,仅作参考)
如果一定要保留datetime列但想通过时间戳赋值,可以手动写访问器和修改器来处理转换:
use Carbon\Carbon; // 存入数据库时,把时间戳转成datetime字符串 public function setCreatedAtAttribute($value) { $this->attributes['created_at'] = Carbon::createFromTimestamp($value)->toDateTimeString(); } // 从数据库读取时,转成Carbon实例 public function getCreatedAtAttribute($value) { return Carbon::parse($value); }
不过这种方式比较繁琐,不如前两种方案直接。
内容的提问来源于stack exchange,提问作者Felipe Peña
相关产品推荐
相关产品推荐

