Yii2.0.37中日期处理需先trim再用strtotime转时间戳,配合date验证器与自定义时间戳校验,数据库类型与PHP类型须对齐,时区统一设为Asia/Shanghai,REST场景下确保字段为safe并正确触发行为。

在 Yii2.0.37 中,表单提交的日期字符串(如 "2026-10-20" 或 "2026-10-20 14:30")默认不会自动转为时间戳,需手动处理或借助规则预处理。校验配置要兼顾“格式合法”和“可转为有效时间”,否则容易出现空值、时区错乱或验证绕过。
日期字段先 trim 再转时间戳
用户可能输入带空格的日期(如 " 2026-10-20 "),直接用 strtotime() 会返回 false,后续存库或比较出错。
- 在
rules()中加'trim'预处理:[['publish_date'], 'trim'] - 紧接着用
'filter'转时间戳:[['publish_date'], 'filter', 'filter' => function ($value) { return $value ? strtotime($value) : null; }] - 再做必填或范围校验,此时操作的是整型时间戳,逻辑更可靠
校验规则要区分“空”和“非法格式”
仅用 required 无法拦截 "abc" 或 "2026-13-01" 这类非法字符串;而 date 验证器只认字符串格式,不保证能转成有效时间戳。
- 组合使用:
[['publish_date'], 'date', 'format' => 'php:Y-m-d']校验格式 - 补充自定义验证,确保可转时间戳:
[['publish_date'], 'validateDateTimestamp'] - 在模型中写方法:
public function validateDateTimestamp($attribute) { if (!is_numeric(strtotime($this->$attribute))) { $this->addError($attribute, '日期格式不正确或超出有效范围'); } }
数据库字段类型与 PHP 类型需对齐
如果数据库字段是 INT(11) 存时间戳,PHP 层必须确保赋值为整数;若字段是 DATETIME,则应传字符串(如 date('Y-m-d H:i:s', $ts)),不能混用。
- 在
beforeSave()中统一转换:if ($this->publish_date && is_numeric($this->publish_date)) { $this->publish_date = date('Y-m-d H:i:s', $this->publish_date); } - 避免在控制器里手动赋值覆盖,例如
$model->publish_date = time();—— 会跳过验证逻辑 - 时区统一设为
Asia/Shanghai(在入口文件或config/web.php中加'timeZone' => 'Asia/Shanghai')
REST 场景下注意安全属性和行为触发
如果是通过 REST 接口接收日期字段,load() 默认只加载 safe 属性,否则 TimestampBehavior 或自定义 filter 都不会执行。
- 确保日期字段在
rules()中声明为safe:[['publish_date'], 'safe'] - 不要在
scenarios()中遗漏该字段,尤其当用了自定义场景时 - 若字段同时用于创建和更新,且需自动填充,建议绑定
TimestampBehavior并显式配置value回调:'value' => function () { return strtotime($this->publish_date) ?: time(); }


















