ThinkPHP6模型时间戳需区分写入与读取:写入由$autoWriteTimestamp控制(如'datetime'配DATETIME字段),读取用获取器或append+getAttr格式化;分页需append虚拟字段触发格式化,模板中管道符格式化需注意参数顺序。

写入格式必须匹配数据库字段类型
模型里设了什么,数据库就得配什么,错配会导致静默失败(比如存进去是 0000-00-00 或 0):
-
'datetime' → 数据库字段必须是
DATETIME或TIMESTAMP,写入值为'2026-08-27 04:24:00' -
'timestamp'(或
'int')→ 字段推荐INT(11),写入值为1756268640(10位整型) -
'date'(TP6.3+ 支持)→ 字段必须是
DATE,只存日期部分'2026-08-27'
别用 true,它只是启用开关,实际格式走全局配置;要精确控制,就直接写字符串值:
protected $autoWriteTimestamp = 'datetime'; // 强制写入 Y-m-d H:i:s protected $createTime = 'created_at'; protected $updateTime = 'updated_at';
读取时想显示成日期字符串?用获取器
数据库存的是 int 时间戳,查出来默认还是数字。想让 $user->create_time 直接返回 '2026-08-27',就得加获取器:
public function getCreateTimeAttr($value)
{
return $value ? date('Y-m-d', (int)$value) : null;
}
注意命名规则:get + 字段名首字母大写 + Attr(如字段是 update_time,方法名就是 getUpdateTimeAttr)。
立即学习“PHP免费学习笔记(深入)”;
分页列表里时间还是数字?得靠 append 配合获取器
paginate() 返回的是 Collection,不自动触发获取器。解决办法是在模型中定义虚拟字段:
protected $append = ['create_time_text', 'update_time_text'];
public function getCreateTimeTextAttr($value, $data)
{
return date('Y/m/d', (int)($data['create_time'] ?? 0));
}
public function getUpdateTimeTextAttr($value, $data)
{
return date('m-d H:i', (int)($data['update_time'] ?? 0));
}
这样调用 $list->toArray() 或输出 JSON 时,会自动带上格式化后的字段,原始时间戳也还在,不冲突。
模板里直接格式化?管道符要小心
如果没在模型里处理,模板里可用:
{$user.create_time|date='Y-m-d H:i:s'}
但前提是 $user.create_time 是整型时间戳。如果是 DATETIME 字符串(如 '2026-08-27 04:24:00'),得先转:
{$user.create_time|strtotime|date='Y-m-d'}
别漏单引号,也别把参数顺序写反——{$time|date='Y-m-d',###} 是正确写法。



















