Yii框架中时间戳字段应使用INT类型存储Unix时间戳,通过TimestampBehavior自动填充、数据库建表设为INT(11)、应用层统一用time()赋值,确保高效、时区中立与跨平台兼容。

Yii 框架中时间戳字段(如 created_at、updated_at)通常建议用 Unix 时间戳(INT 类型)存储,兼顾查询效率、时区中立性和跨平台兼容性。配置关键在于模型层自动填充 + 数据库层正确建表 + 应用层统一处理。
模型中定义时间戳行为
在 ActiveRecord 模型中启用自动时间戳管理,推荐使用 TimestampBehavior:
- 确保模型类继承
yii\db\ActiveRecord - 在
behaviors()方法中添加行为配置:
<?php
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
class Post extends ActiveRecord
{
public function behaviors()
{
return [
'timestamp' => [
'class' => TimestampBehavior::class,
'attributes' => [
ActiveRecord::EVENT_BEFORE_INSERT => ['created_at', 'updated_at'],
ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at'],
],
// 自动写入当前 Unix 时间戳(整数)
'value' => function () {
return time(); // 或 Yii::$app->formatter->asTimestamp(new \DateTime())
},
],
];
}
}
数据库字段类型与迁移配置
建表或修改字段时,必须使用 INT(11) 类型(非 DATETIME 或 TIMESTAMP),避免 MySQL 自动时区转换干扰:
- 创建迁移命令:
yii migrate/create create_post_table - 在
up()中定义字段为整数:
$this->createTable('post', [
'id' => $this->primaryKey(),
'title' => $this->string(),
'created_at' => $this->integer()->notNull(),
'updated_at' => $this->integer()->notNull(),
echo Yii::$app->formatter->asDatetime($model->created_at); // 输出:August 17, 2026 13:57
echo Yii::$app->formatter->asRelativeTime($model->updated_at); // 输出:2 minutes ago
- 查询时按时间范围筛选(注意单位是秒):
$todayStart = strtotime('today');
$todayEnd = strtotime('tomorrow') - 1;
$query = Post::find()->where(['between', 'created_at', $todayStart, $todayEnd]);
注意事项与常见陷阱
使用 Unix 时间戳需避开几个典型问题:
-
不要在数据库层面设默认值(如
DEFAULT CURRENT_TIMESTAMP),这会和 PHP 层的time()产生时区偏差 - 避免混用 DATETIME 和 INT:同一张表中不要同时存在两种时间字段类型,否则关联、排序、分组易出错
-
时区一致性:PHP 的
date_default_timezone_set()和 Yii 应用配置中的'timeZone' => 'Asia/Shanghai'要保持一致,否则asDatetime()显示异常 -
大时间范围查询优化:对
created_at字段加 B-TREE 索引,提升按日期分页或统计的性能


















