Postgres中毫秒级时长转可读格式:突破24小时循环限制,保留累计小时数的实现方案
解决PostgreSQL中毫秒转累计小时格式的问题
这个问题我太熟悉了!你当前的写法之所以会在超过24小时后重置,是因为PostgreSQL的time类型范围仅为00:00:00 到 23:59:59.999999,任何超出这个范围的时间都会被自动截断到一天内,所以70小时会变成70-2*24=22小时,24小时直接变成00:00:00。
要实现累计小时数的格式,我们需要手动拆解毫秒数为总小时数+剩余分秒,而不是依赖time类型的自动转换。这里提供两种简洁的实现方式:
方法一:利用INTERVAL和字符串拼接
这种方式通过取余得到剩余毫秒数,再借助TO_CHAR自动格式化分秒:
SELECT CONCAT( -- 计算总小时数,不足两位补零 LPAD(FLOOR(time_unix::bigint / 3600000)::TEXT, 2, '0'), ':', -- 剩余毫秒转成INTERVAL后格式化成分秒(自动补零) TO_CHAR( MOD(time_unix::bigint, 3600000) * INTERVAL '1 ms', 'MI:SS' ) ) AS human_readable_time FROM test;
方法二:手动拆解秒数
更直接地将毫秒转成总秒数,再拆分小时、分钟、秒:
WITH total_seconds AS ( SELECT time_unix::bigint / 1000 AS sec FROM test ) SELECT CONCAT( LPAD((sec / 3600)::TEXT, 2, '0'), ':', LPAD(((sec % 3600) / 60)::TEXT, 2, '0'), ':', LPAD((sec % 60)::TEXT, 2, '0') ) AS human_readable_time FROM total_seconds;
两种方法的输出都完全符合你的期望:
| human_readable_time |
|---|
| 02:00:00 |
| 08:00:00 |
| 00:30:00 |
| 70:00:00 |
| 24:00:00 |
核心思路就是避开time类型的24小时限制,直接计算累计的小时数,再搭配分秒的补零格式化,就能得到你想要的人类可读格式啦。
内容的提问来源于stack exchange,提问作者Aleeb
相关产品推荐
相关产品推荐

