php 计算时间段内的工作日 与节假日

计算方法是取开始时间后的第一个星期一,如果结束时间大于等这一天则用第一个星期一至结束时间的时间的间隔取整周数与余数计算工作日与周末,再加上第一个周一前一周的工作日与节假日.

 

/** 计算时间段内的工作日 与节假日
 * @param $begin_date \DateTime
 * @param $end_date  \DateTime
 * @return array
 * @throws \Exception
 */
static function computeDays($begin_date,$end_date)
{
 
    if ($end_date >= $begin_date) {
        $begin_week_day = $begin_date->format("N");
        if ($begin_week_day == 1) {
            $cut_week_days = 0;
        } else {
            $cut_week_days = 7 - $begin_week_day + 1;
        }
 
        $dateInterval = new \DateInterval("P" . $cut_week_days . "D");
        $first_monday = $begin_date->add($dateInterval);
 
        //总工作日
        $total_work_days = 0;
        //总节假日
        $total_holidays = 0;
        //总天数,包括起始日期
        $total_days = 0;
        if ($end_date >= $first_monday) {
            $diff = $first_monday->diff($end_date);
            $diff_days = $diff->days + 1; // 包括开始日期 +1
            $weeks_yu = $diff_days % 7;
            $weeks = floor($diff_days / 7);
            $total_days = $diff_days;
            if ($weeks > 0) {
                $total_work_days = $weeks * 5;
                $total_holidays = $weeks * 2;
            }
 
            if ($weeks_yu == 6) {
                $total_holidays += 1;
                $total_work_days += 5;
            } else {
                $total_work_days += $weeks_yu;
            }
 
            if ($cut_week_days > 0) {
                if ($cut_week_days >= 2) {
                    $total_work_days += $cut_week_days - 2;
                    $total_holidays += $cut_week_days + 2;
                } else {
                    $total_holidays += 1;
                }
            }
 
        } else {
            $diff = $first_monday->diff($end_date);
            $diff_days = $diff->days + 1; // 包括开始日期 +1
            $end_week_day = $end_date->format("N");
            if ($begin_week_day <= 5 && $end_week_day <= 5) {
                $total_work_days += $end_week_day - $begin_week_day + 1;
            } elseif ($begin_week_day > 5 && $end_week_day > 5) {
                $total_holidays += $end_week_day - $begin_week_day + 1;
            } elseif ($begin_week_day <= 5 && $end_week_day > 5) {
                $total_work_days += 5 - $begin_week_day + 1;
                $total_holidays += $end_week_day - 5;
            }
 
            $total_days = $end_week_day - $begin_week_day + 1;
        }
 
 
        //判断国家规定节假日     
        /*$project_holidays = ProjectHolidaysModel::where("1=1")
            ->whereBetweenTime("thedate",$begin_date->format("Y-m-d"),$end_date->format("Y-m-d"))
            ->all();*/
         //以2020 五一为例 ,在数据库中加入上班与节假日调整
         //is_holidays 1假期 0上班
         $project_holidays = [
             ["thedate"=>'2020-5-1',"is_holidays"=>1],
             ["thedate"=>'2020-5-4',"is_holidays"=>1],
             ["thedate"=>'2020-5-5',"is_holidays"=>1],
             ["thedate"=>'2020-5-9',"is_holidays"=>0],
         ];
 
 
        foreach ($project_holidays as $one){
            $the_date = new \DateTime($one["thedate"]);
            $the_week_day = $the_date->format("N");
 
            if($the_week_day > 5 && $one["is_holidays"] =="0"){
                $total_holidays -= 1;
                $total_work_days += 1;
            }
            if($the_week_day <=5 && $one["is_holidays"] == "1"){
                $total_holidays += 1;
                $total_work_days -= 1;
            }
        }
 
 
 
        return [
            "total_work_days" => $total_work_days,
            "total_holidays" => $total_holidays,
            "total_days" => $total_days
        ];
 
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值