UNIX_TIMESTAMP() 不带参数或传入合法日期字符串时返回整数,输入非法格式、超出范围或NULL时返回NULL;DATE类型字段上使用该函数会导致索引失效;其结果依赖服务器时区,跨时区需用CONVERT_TZ()校准;FROM_UNIXTIME()默认丢失毫秒精度。

UNIX_TIMESTAMP() 什么时候返回整数,什么时候返回 NULL
UNIX_TIMESTAMP() 的行为取决于参数:不带参数时返回当前秒级时间戳(INT);传入合法日期字符串(如 '2024-03-15 10:30:00')也返回秒级整数;但只要输入格式非法、超出 MySQL 支持范围(如 '9999-99-99')、或为 NULL,它就直接返回 NULL,不会报错。这点容易被忽略——你看到 NULL 结果,往往不是函数坏了,而是源头数据没清洗干净。
传入 DATETIME vs 传入 DATE 类型字段的区别
MySQL 会隐式补全缺失的时间部分:UNIX_TIMESTAMP('2024-03-15') 等价于 UNIX_TIMESTAMP('2024-03-15 00:00:00'),结果是当天零点的秒级时间戳。但如果字段本身是 DATE 类型,在 WHERE 条件中用 UNIX_TIMESTAMP(date_col) > 1710489600,会导致索引失效——因为对列应用了函数。更安全的做法是反过来写:date_col > FROM_UNIXTIME(1710489600),这样能走索引。
跨时区场景下 UNIX_TIMESTAMP() 的陷阱
UNIX_TIMESTAMP() 总是基于 MySQL 服务器当前时区计算。比如服务器设为 'Asia/Shanghai',执行 UNIX_TIMESTAMP('2024-03-15 10:00:00') 得到的是东八区该时刻对应的 UTC 秒数;若服务器时区是 'UTC',同样字符串输入会得到不同结果。线上环境务必确认 SELECT @@time_zone 的值。如果需要稳定转换,建议统一用 CONVERT_TZ() 先转标准时区再调用:UNIX_TIMESTAMP(CONVERT_TZ('2024-03-15 10:00:00', '+08:00', '+00:00'))。
替代方案:FROM_UNIXTIME() 逆向转换要注意精度丢失
FROM_UNIXTIME() 把秒级整数转回 DATETIME,但默认只保留秒级精度。如果你原始时间戳含毫秒(如 JavaScript 的 Date.now()),直接除以 1000 再传入会丢掉毫秒部分。可行做法是先截取前 10 位:FROM_UNIXTIME(FLOOR(1710489600123 / 1000)),或用字符串拼接模拟毫秒显示(MySQL 8.0.28+ 支持 FROM_UNIXTIME(ts, '%Y-%m-%d %H:%i:%s.%f'),但 %f 对应的是微秒,需自行换算)。
真正麻烦的不是函数怎么写,而是时间语义是否清晰——同一个数字在不同时区、不同精度、不同存储类型(INT vs BIGINT)下代表的意义可能完全不同。

















