我有一个函数是MySql,它计算两个给定日期之间的工作日期数,但我想知道它中使用的逻辑。 sql函数如下:
<?php
$returnValue = '[{"id":1,"firstName":"Annemarie","lastName":"Bruening","something":1381105566987,"jobTitle":"Cloak Room Attendant","started":1367700388909,"dob":122365714987,"status":"Suspended"}]';
echo $returnValue;
答案 0 :(得分:2)
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
返回两个日期时间值的日期之间的整数日历天数(生效设置时间为两个日期的00:00:00 + 00000 )。由于DATEDIFF
仅使用日期,因此第二天的持续时间会丢失,因此请添加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