前两天拿到一个让麻了的需求:
实时查询某单据认领时间的时效,啥意思呢?其实就是: 认领时间 - 单据创建时间!
但是还有额外条件,要求当日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;
};
上面就可以计算出时间段内的时间差!!!!!!
起飞!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!