postgresql 时间相关操作

疑似蜜糖 · · Field Notes

今天遇到一个问题,就是其他业务系统过来的时间戳类型为毫秒级如:1635830753393通过postgresql 的to_timestamp函数后,发现时间错误了,得到的时间成为了 53807-06-01 07:29:52.999936经过排查发现时间戳位数问题,于是使用一下方式得到正确的时间

select to_timestamp(1635830753393/1000.0) //保留毫秒精度结果:2021-11-02 05:25:53.393000
select to_timestamp(1635830753393/1000) //不保留毫秒精度结果:2021-11-02 05:25:53.000000

其他内容

-- 当天:
select date_trunc(‘day’,now());
-- 当季第一天
select date_trunc(‘quarter’,now());
-- 当周第一天:
select date_trunc(‘week’,now());
-- 小时 取整:
select date_trunc(‘hour’,now());
-- 获取月初月末日期:
select date_trunc(‘month’,now()+‘1 months’)+‘-1 days’
select date_trunc(‘month’,now() )+‘-1 days’
select date_trunc(‘month’,now() )
-- 当前时间
clock_timestamp() 
--与事务无关
now() 
--在同一个事务里是一样的
-- 时间差
select date_part(‘day’, now()-date’2021-07-29’) --(结果是整天)
select date_part(‘week’, now()) --(当天是多少周)
select EXTRACT(epoch from (now()-date’2021-07-29’))/60/60/24 --(结果是小数)

Replies

北侧工程师

毫秒时间戳直接丢进 to_timestamp,出来公元五万年,属实社死现场。

我们这边现在约定很土:

  • 库里、接口里统一秒,要毫秒就在应用层除;
  • 或者入库前看位数:13 位当毫秒,10 位当秒,写个小函数挡一道,别指望每个人都记得 /1000

date_trunc 那一段也实用。坑点是引号:有的客户端里中文弯引号/直引号混用会直接语法炸,复制示例的时候我被阴过一次。

now() 跟事务绑定、clock_timestamp() 每次变,排查“同事务里时间怎么不动”的时候这个区别救命。