php 处理时间断内去掉部分不统计的时间

186 阅读1分钟

前两天拿到一个让麻了的需求:
实时查询某单据认领时间的时效,啥意思呢?其实就是: 认领时间 - 单据创建时间!
但是还有额外条件,要求当日16.30到次日9点这个时间不统计,啥意思呢?
就比如:2022-07-10  16:25:00  创建了单据
2022-07-11  09:31:00   认领了单据
那么认领时效是     6分钟   !都到这份上了  ,应该都明白啥意思了哈!
那么除了这个条件,还要去掉休息的日子我们单休只能算一个周日,周六还得按照正常上班     来算;
另外还要去掉节假的日子,那么还要考虑到,周日补班的情况。

我的思路:先拿到时间段所有的日期,先确定始末时间是否在当日16.30到次日9点这个时间。
然后循环所有的日期,一天一天的算,把不上班日子去掉。

ps:先维护法定节假日。

好了废话结束上代码:

        $calc_times_tamp = function ($time1,$time2) use ($CFG){  //计算
            $day_time = 86400; //一天
            $c_time = 59400;//当日16.30 到次日9点
            $c_9 = 32400;//9个小时
            //新的计算规则---16:30及以后认领后未出价的询价单,认领处理时效从次日早上9:00开始计算,即16:30后认领未出价的询价单,从认领时间开始至次日早上9:00的时间段不计算在认领时效内。
            $date1 = date('Ymd',$time1);
            $gz_time1 = strtotime($date1);
            $date2 = date('Ymd',$time2);
            $gz_time2 = strtotime($date2);
            $begin_time = function ($time) {
                $beginTime = strtotime(date("Y-m-d 09:00:00", $time));
                return $time > $beginTime ? $time : $beginTime;
            };
            $end_time = function ($time) {
                $endTime = strtotime(date("Y-m-d 16:30:00", $time));
                return  $time > $endTime ? $endTime : $time;
            };
            //查询所有日期
            $get_every_date = function ($date1, $date2){
                $start_time = strtotime($date1);
                $end_time = strtotime($date2);
                $days = ($end_time - $start_time) / 86400;
                $date = [];
                for ($i = 0; $i < ($days + 1); $i++) {
                    $date[] = date("Ymd", $start_time + 86400 * $i);
                }
                return $date;
            };
            //周末查询
            $week_date = function ($date){
                $week = [];
                foreach ($date as $d){
                    if ((date('w', strtotime($d)) == 0)) {
                        $week[] = $d;
                    }
                }
                return $week;
            };
            //时间段所有的日期
            $_every_date =  $get_every_date($date1, $date2);
            //是周末的
            $_week_date = $week_date($_every_date);
            $whereDate  = implode(',',$_every_date);
            $che_date= DB::select("select date, status from {$this->db->pre}work_holiday_date  where date in ( {$whereDate})");
            $che_date = array_column($che_date,null, "date");
            $shang_ban_date = [];//上班的
            $bu_shang_ban_date = [];//不上班
            $_q_date = [];//用于请求
            foreach ($_every_date as $item){
                if (!empty($che_date[$item])){
                    if ($che_date[$item]['status'] == 2){
                        $bu_shang_ban_date[] = $item;
                    }elseif ($che_date[$item]['status'] == 1){
                        if (in_array($item, $_week_date)){
                            $bu_shang_ban_date[] = $item;
                        }else{
                            $shang_ban_date[] = $item;
                        }
                    }else{
                        $shang_ban_date[] = $item;
                    }
                }else{
                    $_q_date[] = $item;
                }
            }
            //先验证时间段
            $time1 = $end_time($begin_time($time1));
            $time2 = $end_time($begin_time($time2));
            $cnum = count($_every_date);
            $res_time = 0;
            $tmp_date = $date1;
            for ($i = 0; $i < $cnum; $i++) {
                if (in_array($tmp_date, $_every_date)) {
                    if (in_array($tmp_date, $shang_ban_date)) { //是上班时间
                        if ($tmp_date == $date2) { //是结束时间
                            $res_time += $time2 - $time1;
                            break;
                        }
                        //没结束  次日时间   减去当前时间   再减去16.30到凌晨的时间
                        $res_time += (strtotime($tmp_date . " 16:30:00")) - $time1;
                    }
                    //次日的9点整
                    $time1 = strtotime($tmp_date) + $day_time + $c_9;
                    $tmp_date = date('Ymd', $time1);
                }
            }

            return $res_time > 0 ? $res_time : 0;
//            $c_day = intval(($gz_time2 - $gz_time1) / $day_time); //相差天数
//            $res_time = $time2 - $time1 - $c_day * $c_time;
//            return $res_time > 0 ? $res_time : 0;
        };

上面就可以计算出时间段内的时间差!!!!!!
起飞!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!