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

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

 


    /** 计算时间段内的工作日 与节假日
     * @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
            ];

        }
    }

Posted in php