MySQL 日期/时间类型选型与时区处理
适用版本:MySQL 8.0+ / Laravel 10+。MySQL 5.7 已 EOL,文中不再覆盖。 一句话结论 「物理时刻」(事件发生于何时)→ TIMESTAMP,自动跟随会话时区转换 「字面值」(合同上写的、用户输入的日期)→ DATETIME,原样存取不转换 仅日期 → DATE;仅时长 → TIME;JS/跨语言毫秒戳 → BIGINT 永远不要用 VARCHAR 存日期——无强制约束、无法范围查询、排序按字符串 选型对照表 类型 范围 字节 时区行为 小数秒 典型场景 DATETIME 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 5 + fsp 字符串原样存取,不转换 DATETIME(0~6) 合同生效时点、用户填写的本地时间、历史事件 TIMESTAMP 1970-01-01 00:00:01 UTC ~ 2038-01-19 03:14:07 UTC 4 + fsp 写入:会话时区 → UTC;读取:UTC → 会话时区 TIMESTAMP(0~6) created_at / updated_at、日志、跨时区事件戳 DATE 1000-01-01 ~ 9999-12-31 3 — — 生日、纪念日、报表日期 TIME -838:59:59 ~ 838:59:59 3 + fsp — TIME(0~6) 营业时长、计时器 YEAR 1901 ~ 2155 1 — — 罕用 BIGINT INT64 8 应用层控制 — JS 毫秒戳、Unix 微秒戳、跨语言互操作 小数秒(fsp,fractional seconds precision) 0~6 位,每 2 位多占 1 字节。Laravel 11+ 默认就用 DATETIME(6) / TIMESTAMP(6)。 ...