UNIX_TIMESTAMP() 默认按服务器时区解析日期,非UTC;传字符串需符合MySQL格式,否则返回0;强制UTC需配合CONVERT_TZ();PG用EXTRACT(EPOCH FROM ...)替代,PHP推荐DateTime类解析。

MySQL 里直接用 UNIX_TIMESTAMP() 转日期字段
只要字段是合法的 DATETIME、DATE 或 TIMESTAMP 类型,UNIX_TIMESTAMP() 就能直接转成秒级时间戳。它默认按服务器时区解析,不是 UTC —— 这点最容易被忽略。
常见错误现象:SELECT UNIX_TIMESTAMP('2023-01-01') 返回值比预期小 8 小时(比如你本地是 CST),因为函数把字符串当成本地时区处理,而不是 UTC。
- 如果传入字符串,必须符合 MySQL 默认格式(
'YYYY-MM-DD HH:MM:SS'或'YYYY-MM-DD'),否则返回0 - 传入
NULL会返回NULL,不是0 - 想强制按 UTC 解析?得先用
CONVERT_TZ()转换,例如:UNIX_TIMESTAMP(CONVERT_TZ('2023-01-01', '+00:00', @@global.time_zone))
PostgreSQL 没有 UNIX_TIMESTAMP(),改用 EXTRACT(EPOCH FROM ...)
PostgreSQL 把时间戳当 TIMESTAMP WITH TIME ZONE 处理,EXTRACT(EPOCH FROM ...) 返回的是从 UTC 1970-01-01 开始的秒数(带小数),结果和 MySQL 的 UNIX_TIMESTAMP() 语义一致,但类型是 double precision。
使用场景:迁移 MySQL 代码到 PG,或需要跨数据库兼容时间戳逻辑时。
- 对
TIMESTAMP WITHOUT TIME ZONE字段执行EXTRACT(EPOCH FROM col),会按当前timezone设置隐式转成带时区再计算,结果可能偏移 - 稳妥做法是显式转时区:
EXTRACT(EPOCH FROM col AT TIME ZONE 'UTC') - 如果字段已经是
TIMESTAMP WITH TIME ZONE,直接EXTRACT(EPOCH FROM col)即可,无需额外转换
PHP 中用 strtotime() 或 DateTime::getTimestamp() 接收 SQL 返回的日期字符串
SQL 查询返回的日期通常是字符串(如 "2023-10-05 14:23:18"),PHP 不会自动识别为时间戳。别直接 (int)$row['created_at'] —— 那只会截断成 2023。
性能影响:在 PHP 层批量转换比在 SQL 层转换更耗 CPU,尤其数据量大时;但灵活性更高(比如要统一转成某个时区)。
-
strtotime()支持模糊格式,但遇到非法字符串会返回false,容易引发静默错误 - 推荐用
DateTime类:(new DateTime($row['created_at']))->getTimestamp(),可捕获异常,且支持时区控制 - 如果 SQL 已经用
UNIX_TIMESTAMP(col)返回整数,PHP 直接接收即可,不用再解析
时区不一致导致时间戳错乱的典型表现
最常踩的坑不是函数不会用,而是没意识到「同一个时间字符串,在不同环境里解析出的时间戳可能差好几千秒」。
典型现象:开发机查出来是 1672531200(对应 2023-01-01 00:00:00 UTC),生产库查出来却是 1672502400(少 8 小时),因为生产 MySQL 的 time_zone 是 '+00:00',而开发是 'SYSTEM'(即东八区)。
- 检查 MySQL 当前时区:
SELECT @@time_zone, @@system_time_zone - 应用层连接后立刻执行:
SET time_zone = '+00:00',确保所有UNIX_TIMESTAMP()行为一致 - 存储时间时统一用
TIMESTAMP类型(自动转 UTC 存),别用DATETIME(纯字面值,不及时区)

















