我有一个函数是 MySql,它计算两个给定日期之间的工作日期数,但我想知道其中使用的逻辑。 sql函数如下:
CREATE FUNCTION TOTAL_WEEKDAYS(date1 DATE, date2 DATE)
RETURNS INT
RETURN ABS(DATEDIFF(date2, date1)) + 1
- ABS(DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY),
ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY))) / 7 * 2
- (DAYOFWEEK(IF(date1 < date2, date1, date2)) = 1)
- (DAYOFWEEK(IF(date1 > date2, date1, date2)) = 7);
最佳答案
ABS(DATEDIFF(date2, date1)) + 1
- ABS(DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY),
ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY))) / 7 * 2
- (DAYOFWEEK(IF(date1 < date2, date1, date2)) = 1)
- (DAYOFWEEK(IF(date1 > date2, date1, date2)) = 7)
;
ABS
用于确保每个结果都是正整数,以防日期向后(如果起点在终点之后)。
ABS(DATEDIFF(date2, date1)) + 1
DATEDIFF
返回 2 个日期时间值的 dates 之间的日历天数(实际上将两者的时间设置为 00:00:00+00000日期)。因为 DATEDIFF
使用日期,只有第二天的 duration 丢失,所以加 1 进行补偿。
- ABS(DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY),
ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY))) / 7 * 2
使用 ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY)
和 ADDDATE(date1, INTERVAL 1) 计算两个日期的一周开始 - DAYOFWEEK(date1) DAY)
然后获取这些日期之间的天数。将该数字除以 7 得到日期之间跨越的周数。将该数字乘以 2 得到跨度中涉及的周末天数。从先前计算的原始天数中减去这些周末天数,得出日期之间的工作日总数。
然而,给定的开始/结束日期时间可能单独在周末,所以:
- (DAYOFWEEK(IF(date1 < date2, date1, date2)) = 1)
如果给定日期之一是星期日,则减去 1
- (DAYOFWEEK(IF(date1 > date2, date1, date2)) = 7)
如果给定日期之一是星期六,则减去 1
得出工作周不包括周六和周日的“工作日”数。
如果您感兴趣,这里有一个查询将每个函数或函数调用集分解为单独的列,以便您可以对其进行跟踪。调整提供 2 个日期的子查询以适应。
select
date1
, date2
, DATEDIFF(date2, date1) "datediff"
, ABS(DATEDIFF(date2, date1)) abs_datediff
, ABS(DATEDIFF(date2, date1)) + 1 diff_2end_dt
, DAYOFWEEK(date2) dt2_dow
, ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY) start_of_wk_dt2
, DAYOFWEEK(date1) dt1_dow
, ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY) start_of_wk_dt1
, DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY),
ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY)) diff_wksby7
, ABS(DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY),
ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY))) abs_diff_wksby7
, ABS(DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY),
ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY))) / 7 * 2 diff_wkends
, DAYOFWEEK(IF(date1 < date2, date1, date2)) dow_min
, DAYOFWEEK(IF(date1 > date2, date1, date2)) dow_max
from (
select date_add(now(), INTERVAL -34 DAY) as date1, date_add(now(), INTERVAL -2 DAY) as date2
) d
关于mysql - 两个日期之间的工作日数[逻辑],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46726897/