这个问题要求不考虑公共假期,因此该答案仅计算工作时间,考虑周末,但忽略可能的公共假期。
如果您需要考虑公共假期,则需要单独建立一个表格,列出公共假期的日期,这些日期可能会因年份、州或国家的不同而有所不同。主公式可能保持不变,但您需要从其结果中减去落在给定日期范围内的公共假期小时数。
让我们创建一个包含各种情况的示例数据表:
CREATE TABLE T (CreatedDate datetime, UpdatedDate datetime);
INSERT INTO T VALUES
('2012-03-05 09:00:00', '2012-03-05 15:00:00'),
('2012-03-05 10:00:00', '2012-03-06 10:00:00'),
('2012-03-05 11:00:00', '2012-03-06 10:00:00'),
('2012-03-05 10:00:00', '2012-03-06 15:00:00'),
('2012-03-09 16:00:00', '2012-03-12 10:00:00'),
('2012-03-06 16:00:00', '2012-03-15 10:00:00'),
('2012-03-09 16:00:00', '2012-03-19 10:00:00');
在 MS SQL Server 中,我使用以下公式:
SELECT
CreatedDate,
UpdatedDate,
DATEDIFF(minute, CreatedDate, UpdatedDate)/60.0 -
DATEDIFF(day, CreatedDate, UpdatedDate)*16 -
DATEDIFF(week, CreatedDate, UpdatedDate)*16 AS BusinessHours
FROM T
这将产生以下结果:
+
| CreatedDate | UpdatedDate | BusinessHours |
+
| 2012-03-05 09:00:00 | 2012-03-05 15:00:00 | 6 |
| 2012-03-05 10:00:00 | 2012-03-06 10:00:00 | 8 |
| 2012-03-05 11:00:00 | 2012-03-06 10:00:00 | 7 |
| 2012-03-05 10:00:00 | 2012-03-06 15:00:00 | 13 |
| 2012-03-09 16:00:00 | 2012-03-12 10:00:00 | 2 |
| 2012-03-06 16:00:00 | 2012-03-15 10:00:00 | 50 |
| 2012-03-09 16:00:00 | 2012-03-19 10:00:00 | 42 |
+
这段代码的作用是,因为在SQL Server中DATEDIFF
返回指定datepart边界之间经过的计数,从而计算出指定startdate和enddate之间经过的时间。
每天有8个工作小时。我计算出两个日期之间的总工作小时数,然后减去半夜的数量乘以每天16个非工作小时,再减去周末的数量乘以16(周六+周日8+8个工作小时)。
它还假设给定的开始和结束日期/时间都在工作时间内。
在MySQL中,最接近的等效方法是TIMESTAMPDIFF
,但它的工作方式不同。它实际上计算秒数差异并除以所选择的unit的秒数(舍弃小数部分)。
因此,为了得到所需的结果,我们可以计算某个锚定日期和CreatedDate
和UpdatedDate
之间的TIMESTAMPDIFF
,而不是直接计算CreatedDate
和UpdatedDate
之间的差异。
我选择了2000-01-03 00:00:00
,这是一个星期一。您可以选择任何其他星期一(或星期天,如果您的星期从星期日开始)午夜作为锚定日期。
MySQL查询变成了(请参见 SQL Fiddle):
SELECT
CreatedDate,
UpdatedDate,
TIMESTAMPDIFF(MINUTE, CreatedDate, UpdatedDate)/60.0 -
16*(
TIMESTAMPDIFF(DAY, '2000-01-03',UpdatedDate)-
TIMESTAMPDIFF(DAY, '2000-01-03',CreatedDate)
) -
16*(
TIMESTAMPDIFF(WEEK, '2000-01-03',UpdatedDate)-
TIMESTAMPDIFF(WEEK, '2000-01-03',CreatedDate)
) AS BusinessHours
FROM T