两个日期之间的工作天数[LOGIC]

时间:2017-10-13 09:37:17

标签: mysql

我有一个函数是MySql,它计算两个给定日期之间的工作日期数,但我想知道它中使用的逻辑。 sql函数如下:

<?php
$returnValue = '[{"id":1,"firstName":"Annemarie","lastName":"Bruening","something":1381105566987,"jobTitle":"Cloak Room Attendant","started":1367700388909,"dob":122365714987,"status":"Suspended"}]';
echo $returnValue;

1 个答案:

答案 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