MySQL用FROM_UNIXTIME()转秒级时间戳,PostgreSQL需TO_TIMESTAMP()配合类型转换,SQLite依赖datetime()加unixepoch修饰符;三者单位、类型、函数均不兼容,须在应用层统一处理。

MySQL里用 FROM_UNIXTIME() 转秒级时间戳
MySQL原生支持秒级Unix时间戳(10位整数)转日期,直接用 FROM_UNIXTIME() 就行。它默认返回 YYYY-MM-DD HH:MM:SS 格式,可读性强,也支持自定义格式。
常见错误是传入毫秒级时间戳(13位),结果变成公元3万年——因为MySQL按秒处理,13位会被当“秒”解析。
- 正确用法:
SELECT FROM_UNIXTIME(1717027200);→2024-05-31 00:00:00 - 转指定格式:
SELECT FROM_UNIXTIME(1717027200, '%Y年%m月%d日 %H:%i'); - 若字段是毫秒级,先除以1000:
FROM_UNIXTIME(UNIX_TIMESTAMP_COLUMN / 1000)
PostgreSQL中用 TO_TIMESTAMP() 处理秒和毫秒
PostgreSQL的 TO_TIMESTAMP() 默认接收的是秒级浮点数,但必须注意:它把输入当作“秒 since epoch”,不接受整数类型直接传入(会报错“function to_timestamp(integer) does not exist”)。
常见坑是没显式转类型,或混淆毫秒/秒单位。
- 秒级整数:写成
TO_TIMESTAMP(1717027200::double precision) - 毫秒级整数:先除以1000,再转浮点:
TO_TIMESTAMP(1717027200000::double precision / 1000) - 配合
AT TIME ZONE调时区:TO_TIMESTAMP(1717027200)::timestamptz AT TIME ZONE 'Asia/Shanghai'
SQLite里没有内置函数,得靠 datetime() + unixepoch
SQLite不认 FROM_UNIXTIME 或 TO_TIMESTAMP,但它在 datetime() 函数里悄悄支持了 unixepoch 修饰符——这是唯一可靠方式。
关键点:unixepoch 只接受秒级整数;传毫秒会溢出为错误日期(比如显示1970年)。
- 标准用法:
SELECT datetime(1717027200, 'unixepoch'); - 加本地时区偏移:
SELECT datetime(1717027200, 'unixepoch', 'localtime'); - 毫秒需先整除:
datetime(1717027200000 / 1000, 'unixepoch')(注意用/不是//,SQLite整除会截断)
跨数据库兼容写法几乎不存在,别硬套
三个主流数据库的函数名、参数类型、单位约定全都不一样:MySQL吃整数秒,PostgreSQL要浮点秒,SQLite靠修饰符。试图用一层封装函数“统一接口”反而容易在边界 case(比如0、负值、毫秒误传)上翻车。
真正省事的做法是:在应用层就确认好时间戳单位,并根据目标数据库选对应函数。如果SQL要跑多库,建议把转换逻辑提到代码里做(例如Python用 datetime.fromtimestamp()),SQL只存裸数值。
最容易被忽略的是时间戳来源——前端JS的 Date.now() 是毫秒,后端Go的 time.Now().Unix() 是秒,混在一起不校验单位,查出来的时间永远差1000倍。

















