订单产生的时间你是知道的呀,然后你获取自定义的时间间隔(比如是5),用订单时间加上自定义时间,看 小时 的那里是否落在了 0-9 和 18-23,如果是的话,你再加15个小时,不就获得了需要延时执行的时间了吗? 订单产生时间为 2023-10-08 15:00,加5个小时为 2023-10-08 20:00,小时落在了 18-23 这个区间,所以在 2023-10-08 20:00 基础上加15个小时,得到 2023-10-09 11:00
就是个计算逻辑,你正常延时时间为5*3600=18000s。这个时候先计算当前时间是否大于当天18:00,是的话,直接第二天9点+18000即为关闭时间。如果当前时间小于18点,则用18点的时间戳-当前时间,如果结果大于18000,则表示5小时后,还不到下班时间,直接用当前时间+18000位关闭时间。如果小于18000,则结束时间为第二天9点+(18000-上一侧小于的那个值)。不知道理解的对不对
先计算订单的超时时间 = 订单开始时间 + 自定义时间 如果计算出来的时间 在18:00以后 则更正为真正的失效时间
如果订单在18:00 - 09:00之内 就分为两种情况 订单的超时时间 = 订单开始时间 + 自定义时间 假如超时时间还在下班时间之内那么更正失效时间为第二天的上班时间加上自定义的时间,如果超时时间在上班时间之外,自定义时间 - (超时时间-9:00)+09:00
以下内容由chatGPT生成。
function calculateDeadline(DateTime $orderTime, $hours) {
$workingStart = 9; // 工作开始时间
$workingEnd = 18; // 工作结束时间
$deadline = clone $orderTime;
$deadline->add(new DateInterval('PT' . $hours . 'H'));
// 如果订单在工作时间外创建,或者截止时间在工作时间外,需要进行调整
if ($orderTime->format('H') < $workingStart || $orderTime->format('H') >= $workingEnd || $deadline->format('H') < $workingStart || $deadline->format('H') >= $workingEnd) {
// 计算订单创建时间到当天工作结束的剩余时间
$remainingHoursToday = $workingEnd - $orderTime->format('H');
if ($remainingHoursToday < 0) {
$remainingHoursToday = 0;
}
// 如果剩余时间小于所需时间,那么截止时间将在第二天的工作时间内
if ($remainingHoursToday < $hours) {
$hours -= $remainingHoursToday;
$deadline = clone $orderTime;
$deadline->setTime($workingStart, 0, 0);
$deadline->add(new DateInterval('P1D')); // 增加一天
$deadline->add(new DateInterval('PT' . $hours . 'H'));
} else {
if ($deadline->format('H') >= $workingEnd) {
$overHours = $deadline->format('H') - $workingEnd;
$deadline->setTime($workingStart + $overHours, 0, 0);
$deadline->add(new DateInterval('P1D')); // 增加一天
}
}
}
return $deadline;
}
$orderTime = new DateTime(); // 假设现在就是订单生成的时间
$hours = 5; // 客服需要在5小时内处理订单
$deadline = calculateDeadline($orderTime, $hours);
echo $deadline->format('Y-m-d H:i:s'); // 输出订单的截止时间
订单时间 与 下班时间 18:00 相差小时数 X 小于等于 指定时间间隔 N (这里为5), 取消订单时间为 09:00 加上 (N-X) 个小时 :flushed: 不知道行不行
处理时间 = 5 * 3600
今日剩余时间 = 下班时间减订单产生时间 > 0?下单时间减订单产生时间:0
if(今日剩余时间 > 处理时间){
取消订单时间 = 订单产生时间 + 处理时间
}
第二天剩余时间 = 处理时间减今日剩余时间
上班总时间 = (18:00-9:00)*3600
if(第二天剩余时间> 上班总时间){
天数 = 第二天剩余时间%上班总时间
间隔上班总时间=天数*上班总时间
取消订单时间=(今天+1+天数)的9:00+(第二天剩余时间-间隔上班总时间)
}
取消订单时间 = 第二天上班时间 + 第二天剩余时间
初始化三个变量1.当前时钟初始值为订单时间2.处理剩余时间(题目中是5)3.累计时间,向前推进距离订单时间的小时数
三个方法1潜进器,当前时钟落在9-18点外,潜进至下个9点,时钟更新至9,累计时间增加(到9点的时差),剩余时间不变。2.探进器,时钟落在9-18点,探进至18点,如未探过18点,则剩余时间减至0,累计时间增加,如探过18点,剩余时间减少(到18点的距离),累计时间到18点,时钟至18点。3调度器,判断时钟在9-18内还是外,决定调用潜进器还是探进器,潜进器和探进器调用后都再次调用调度器,直到剩余时间为0,三个方法都不会再调用,执行完毕,此时订单时间加上累计时间即截止时间。
以节点向前推,哪些累加,哪些减少,就这么个思路,可以完善一下,比如时钟换成日期,理论上传入一个时间点,也可以计算当前剩余时间
也可用分配来解决 大概逻辑:
$order_at = Carnbon()->now();
$cancel_time = 3600 * 5; // 把每秒算一个分配点
while($cancel_time >= 0) {
$time = 0; // 可用分配点 声明
if ($order_at->isToday()) { // 如果是今天 则上班时间为当前
$start_at = Carbon::now();
}else{ // 否则上班时间为 第二天的9:00:00 因为循环 每次都会+1天
$start_at = $order_at->addDay(1)->setTime(9,0,0);
}
// 求上班时间 到 下班时间可用的分配点 (下班时间 - 上班时间)
$time = $order_at->clone()->setTime(18,0,0)->sub(
$start_at
)->toSec(); // clone是为了不影响$order_at对象 ps:函数我可能记错 肯定有这些方法
if($cancel_time > $time){
$time = $cancel_time; // 时间足够了 不需要使用最大时间
}
$cancel_time -= $time;
$start_at->addSeconds($time); // 增加秒数
$order_at = $start_at;
}
不考虑周末节假日的情况
public function getDealDate($hour)
{
$second = (int) $hour * 3600;
$leftSeconds = Carbon::today()
->setHour(18)
->diffInSeconds(Carbon::now());
if ($second < $leftSeconds) {
return Carbon::now()
->addSeconds($second)
->toDateTimeString();
}
$second -= $leftSeconds+1;
return Carbon::tomorrow()
->addDays($second / (3600 * 9))
->addHours(9)
->addSeconds($second % (3600 * 9))
->toDateTimeString();
}
推荐文章: