PostgreSQL如何将带毫秒的Unix纪元时间转换为timestamptz?
问题根因
PostgreSQL内置的to_timestamp()函数入参默认单位为秒级Unix纪元值,直接传入毫秒级数值时,函数会把毫秒数识别成秒数计算,最终得到的时间会比真实值放大1000倍,出现严重偏差——你截图里的错值就是因为传入的1611150788148被识别成了秒数,直接算到了公元5万多年的时间点。
另外你之前使用的at time zone 'UTC'逻辑存在使用误区:to_timestamp()本身的返回值就是timestamptz(带时区时间戳)类型,拼接at time zone 'UTC'会把带时区的时间值转换为对应时区下的无时区timestamp类型,反而丢失了你需要的timestamptz属性。
正确转换写法
- 核心调整:将毫秒级纪元值除以1000.0(用浮点数除法保留毫秒精度,避免整数除法截断毫秒值)后,再传入
to_timestamp() - 针对你提到的毫秒值
1611150788148,正确SQL为:
SELECT to_timestamp(1611150788148 / 1000.0);
- 执行后返回的结果为
2021-01-20 13:53:08.148+00,完全匹配你预期的带毫秒精度的timestamptz类型值。
常见使用场景
如果毫秒值是存储在数据库表的bigint类型字段中(比如字段名为event_epoch_ms),批量转换的写法为:
SELECT event_id, to_timestamp(event_epoch_ms / 1000.0) AS event_time_tstz FROM event_table;
注意点:不要用整数形式的
1000做除数,比如1611150788148 / 1000是整数运算,会直接截断末尾的148毫秒,丢失精度,必须使用1000.0触发浮点运算,完整保留毫秒级精度。
内容的提问来源于stack exchange,提问作者Mistu4u
相关产品推荐
相关产品推荐

