最省心做法是直接用官方TimestampBehavior默认配置,因其value返回time()整型时间戳,天然匹配INT字段;需统一PHP时区并转换显示格式,严禁INT与DATETIME字段混用同一逻辑。

数据库字段用 INT 类型存时间戳(如 created_at、updated_at),Yii 中最省心的做法就是直接用官方 TimestampBehavior,保持默认配置即可。
行为配置保持默认
因为 TimestampBehavior 的 value 默认返回 time()(整型时间戳),天然匹配 INT 字段:
- 不用改
value回调,不需写date('Y-m-d H:i:s')这类字符串 - 字段类型是
INT(11)或BIGINT,就直接用原生行为 - 示例配置:
public function behaviors()
{
return [
'timestamp' => [
'class' => \yii\behaviors\TimestampBehavior::class,
'attributes' => [
'created_at' => self::EVENT_BEFORE_INSERT,
'updated_at' => [self::EVENT_BEFORE_INSERT, self::EVENT_BEFORE_UPDATE],
],
],
];
}
确保时区统一,避免值偏移
INT 存的是 Unix 时间戳(秒数),它本身与时区无关,但 PHP 生成时依赖当前时区设置:
- 务必在项目入口(如
web/index.php)顶部设好:date_default_timezone_set('Asia/Shanghai'); - 同时检查
php.ini中date.timezone = "Asia/Shanghai"并已重启服务 - 否则
time()可能按服务器默认时区(如 UTC)生成,导致存进去的值比北京时间少 8 小时
读取和显示时注意转换
数据库读出的是整数,前端不能直接显示。需在模型或视图中转成可读格式:
- 推荐在模型加 getter 方法:
public function getCreatedAtFormatted() { return $this->created_at ? date('Y-m-d H:i', $this->created_at) : ''; } - GridView 中可这样用:
['attribute' => 'created_at', 'format' => ['date', 'php:Y-m-d H:i'], 'value' => 'createdAtFormatted'] - 避免直接对 INT 字段用
formatter->asDate()——它会误把时间戳当日期字符串处理
别和 DATETIME 字段混用同一套逻辑
如果数据库字段是 DATETIME,却用了 INT 行为配置,会导致插入失败或存入 0000-00-00;反之,字段是 INT 却手动返回字符串,会触发 MySQL 类型转换警告甚至截断。
核心就一条:字段类型决定 behavior 的 value 返回值类型。INT → 整数;DATETIME/TIMESTAMP → 字符串或 Expression('NOW()')。


















