from_unixtime函数用于将unix时间戳(秒级整数)转换为可读日期时间,默认返回'y-m-d h:i:s'格式;支持可选format参数自定义输出,并受时区影响,毫秒级时间戳需先除以1000,null或非法输入返回null。

FROM_UNIXTIME函数的基本用法和参数差异
FROM_UNIXTIME 是 MySQL 里把 Unix 时间戳(秒级整数)转成可读日期时间的核心函数。它默认输出格式是 'Y-m-d H:i:s',比如 FROM_UNIXTIME(1717027200) 返回 '2024-05-30 00:00:00'。
但要注意:
- 如果传入的是毫秒级时间戳(比如 JavaScript 的
Date.now()),直接用会出错——得先除以 1000 并用FLOOR或CAST转整型,例如FROM_UNIXTIME(FLOOR(1717027200000 / 1000)) - 第二个参数可指定格式,类似
DATE_FORMAT的语法:FROM_UNIXTIME(1717027200, '%Y年%m月%d日')→'2024年05月30日' - 传入 NULL 或非法数值(如负数超出范围、非数字字符串)时返回 NULL,不会报错,容易漏掉脏数据
常见错误:时区导致的日期偏移
MySQL 默认用系统时区解析时间戳,但 FROM_UNIXTIME 实际上是“把时间戳当作 UTC 值,再按当前会话时区转换显示”。这意味着:
- 服务器时区设为
+08:00,FROM_UNIXTIME(0)显示为'1970-01-01 08:00:00',而非 UTC 的'1970-01-01 00:00:00' - 如果业务要求统一展示 UTC 时间,得先切换会话时区:
SET time_zone = '+00:00';,再执行FROM_UNIXTIME - 更稳妥的做法是显式用
CONVERT_TZ:CONVERT_TZ(FROM_UNIXTIME(ts), '+00:00', '+08:00'),避免依赖会话配置
替代方案:PostgreSQL 和 SQLite 怎么办
MySQL 的 FROM_UNIXTIME 在其他数据库里没有同名函数:
- PostgreSQL 用
TO_TIMESTAMP(ts)(秒级)或TO_TIMESTAMP(ts/1000.0)(毫秒级),返回TIMESTAMP WITH TIME ZONE类型 - SQLite 没有原生时间戳函数,得靠
datetime(ts, 'unixepoch'),注意它只接受秒级;毫秒需先除以 1000:datetime(ts/1000, 'unixepoch') - 所有数据库对空值、溢出值(如大于 2147483647 的秒级时间戳)处理不一致:MySQL 返回 NULL,PostgreSQL 报错,SQLite 可能返回异常字符串
性能与索引注意事项
FROM_UNIXTIME 是计算型函数,出现在 WHERE 或 ORDER BY 中会导致全表扫描:
- ❌ 错误写法:
WHERE FROM_UNIXTIME(created_ts) > '2024-01-01'—— 无法走created_ts索引 - ✅ 正确写法:
WHERE created_ts > UNIX_TIMESTAMP('2024-01-01'),把日期转回时间戳去比 - 如果频繁按日期范围查,建议额外建生成列(MySQL 5.7+):
date_only DATE AS (DATE(FROM_UNIXTIME(created_ts))) STORED,再给该列加索引
时区逻辑和函数边界行为最容易被忽略,尤其是跨数据库迁移或前端传毫秒时间戳时,一不留神就差 8 小时或全表变 NULL。











