首页 > 数据库 > mysql教程 > 如何计算 PostgreSQL 中两个日期之间的工作时间,排除周末并考虑具体工作时间?

如何计算 PostgreSQL 中两个日期之间的工作时间,排除周末并考虑具体工作时间?

Patricia Arquette
发布: 2024-12-29 06:56:11
原创
639 人浏览过

How to Calculate Working Hours Between Two Dates in PostgreSQL, Excluding Weekends and Considering Specific Working Hours?

计算 PostgreSQL 中 2 个日期之间的工作时间

问题:

给定两个时间戳,确定工作小时数其中,将周末视为非工作日,工作时间为上午 8:00 至下午 3:00。

示例:

  • 时间戳: 12 月 3 日 14:00 至 12 月 4 日 9:00
  • 工作中时间:2小时(12月3日=1小时,12月4日=1小时)
  • 时间戳:12月3日15:00至12月7日8:00
  • 工作时间:8小时(12月3 日 = 0 小时,12 月 4 日 = 8 小时,12 月 5 日 = 0 小时,12 月 6 日 = 0 小时,12 月 7 日 = 0 小时)

解决方案 - 四舍五入结果:

SELECT count(*) AS work_hours
FROM   generate_series (timestamp '2013-06-24 13:30',
                      timestamp '2013-06-24 15:29' - interval '1h',
                      interval '1h') h
WHERE  EXTRACT(ISODOW FROM h) < 6
AND    h::time >= '08:00'
AND    h::time <= '14:00';
登录后复制

解决方案 - 更多精度:

使用较小的时间单位(例如 5 分钟切片)可提供更高的精度:

SELECT count(*) * interval '5 min' AS work_interval
FROM   generate_series (timestamp '2013-06-24 13:30',
                      timestamp '2013-06-24 15:29' - interval '5 min',
                      interval '5 min') h
WHERE  EXTRACT(ISODOW FROM h) < 6
AND    h::time >= '08:00'
AND    h::time <= '14:55';
登录后复制

解决方案 - 精确结果:

要获得精确到微秒级别的精确结果,请使用以下命令方法:

SELECT t_id
     , COALESCE(h.h, '0')  -- add / subtract fractions
       - CASE WHEN EXTRACT(ISODOW FROM t_start) < 6
               AND t_start::time > v_start
               AND t_start::time < v_end
         THEN t_start - date_trunc('hour', t_start)
         ELSE '0'::interval END
       + CASE WHEN EXTRACT(ISODOW FROM t_end) < 6
               AND t_end::time > v_start
               AND t_end::time < v_end
         THEN t_end - date_trunc('hour', t_end)
         ELSE '0'::interval END                 AS work_interval
FROM   t CROSS JOIN var
LEFT   JOIN (  -- count full hours, similar to above solutions
   SELECT t_id, count(*)::int * interval '1h' AS h
   FROM  (
      SELECT t_id, v_start, v_end
           , generate_series (date_trunc('hour', t_start)
                            , date_trunc('hour', t_end) - interval '1h'
                            , interval '1h') AS h
      FROM   t, var
      ) sub
   WHERE  EXTRACT(ISODOW FROM h) < 6
   AND    h::time >= v_start
   AND    h::time <= v_end - interval '1h'
   GROUP  BY 1
   ) h USING (t_id)
ORDER  BY 1;
登录后复制

以上是如何计算 PostgreSQL 中两个日期之间的工作时间,排除周末并考虑具体工作时间?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板