mysql計算兩個時間戳/日期間的工作日,兼容節假日


設置起止時間參數
set @date1='2019/01/01';
set @date2='2019/12/31';
建表
DROP TABLE IF EXISTS `calendar`;
CREATE TABLE `calendar` (
  `day` date DEFAULT NULL,
  `holiday` int(11) DEFAULT '0',
  `dow` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
寫入時間函數
delimiter $$
    drop procedure if exists test;
    create procedure test()
    begin
        declare tday date;
        set tday=@date1;
        while (tday <= @date2) do
            insert into calendar(day) values(tday);
            set tday=date_add(tday,interval 1 day);
    end while;
end$$
調用存儲過程
call test();
更新星期數據
update calendar set dow=dayofweek(day)-1;
update calendar set dow=7 where dow=0;
使用
SELECT COUNT(*) FROM calendar
WHERE day BETWEEN @date1 AND @date2 
AND ((DAYOFWEEK(day) NOT IN(1,7) AND holiday=0) or holiday=2);
排除周末
delimiter //
drop function if exists getworkdays;
create function getworkdays(s varchar(16),e varchar(16))
returns varchar(16)
begin
DECLARE result VARCHAR(16) default '';
set e = FROM_UNIXTIME(e,'%Y-%m-%d');
set s = FROM_UNIXTIME(s,'%Y-%m-%d');
select  (floor(days/7)*5 
    + days%7
    - case when 6 between wd and wd+days%7-1 then 1 else 0 end
    - case when 7 between wd and wd+days%7-1 then 1 else 0 end) into  result
from 
(select datediff(e,s)+1 as days, weekday(s)+1 as wd ) as a;
RETURN result;
end //

delimiter ;

## 函數分析


1、編寫存儲過程,便於測試。存儲過程命名為getWorkDays(d1,d2)
2、先求出日期d1到d2之間的天數days【使用datediff()函數】,再求出d2所在的日期為星期幾【使用weekday()函數】
3、使用floor()函數求出days中所包含的星期數為(floor(days/7)),那么工作日數就是floor(days/7)*5。
4、最后一步就是求出零散的工作日:days%7表示的是,當前日期被7整除后的余數,這個余數就是代表零散的天數。但是我們不能將這個零散的天數全部加上,因為這個零散的天數中可能包含着周六,周末。這就是為什么我們前面計算d2是星期幾的原因。
針對上述問題,后面再接上case when()語句,其中的between wd and wd+days%7-1意思就是指周六或者周末是不是在多出來的這個零散日期里。【需要注意這里的wd是weekday(s)即開始時間的星期,筆者在這個位置坑了好久!!】
--------------------- 

以上來自:https://blog.csdn.net/liu16659/article/details/82584807 

排除節假日

delimiter //
drop function if exists getworkdays;
create function getworkdays(s varchar(16),e varchar(16))
returns varchar(16)
begin
DECLARE result VARCHAR(16) default '';
set e = FROM_UNIXTIME(e,'%Y-%m-%d');
set s = FROM_UNIXTIME(s,'%Y-%m-%d');
select count(*) into result from calendar where holiday = 0 and day between s and e
RETURN result;
end //
delimiter ;

注:節假日需要維護calendar表

calendar數據錄入
<?php
// 工作日對應結果為 0, 休息日對應結果為 1, 節假日對應的結果為 2;
date_default_timezone_set('PRC');
$day='2019';
$url='http://tool.bitefu.net/jiari/vip.php?type=0&apikey=123456&d='.$day;
$result=curlget($url);
function curlget($url){
    $ch = curl_init();
    curl_setopt ($ch, CURLOPT_URL, $url);
    curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT,10);
    $dxycontent = curl_exec($ch);
    curl_close($ch);
    return $dxycontent;
}
$conn = mysqli_connect('localhost','root','');
if(!$conn){
	var_dump(mysqli_error());
}

$jsonDay = json_decode($result,true);
$dayData = $jsonDay['data']['2019'];
mysqli_select_db($conn,'efuzhou3');

$sql = "select * from calendar";

$res = mysqli_query($conn,$sql);
while($row=mysqli_fetch_assoc($res)){
	$timestamp = strtotime($row['day']);
	$mdData = date('md',$timestamp);
	if(isset($dayData[$mdData])){
	    $row['holiday'] = $dayData[$mdData];
	}
	$sql = "update calendar set holiday = $row[holiday] where `day` = '$row[day]'";
	mysqli_query($conn,$sql);
	$data[] = $row;
}
var_dump($data);
?>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM