为了账号安全,请及时绑定邮箱和手机立即绑定

根据工作时间和工作日的分钟数计算 SLA

根据工作时间和工作日的分钟数计算 SLA

PHP
慕勒3428872 2023-08-11 15:31:03
我正在尝试构建一个函数,该函数根据工作时间计算票务服务协议,并跳过非工作时间和周末的计算,并将时间相应地转移到第二天或下一个工作日。我对工单的响应 SLA 是 30 分钟,如果工单插入日期在工作日 {周一至周五} 和工作时间内 {08:00:00 - 17:00:00},那么我的结束日期应根据以下公式计算因素:对于周一至周四,如果 insertDate 落在工作时间内,则时间应移至工作时间的下 30 分钟,例如 if case1: insertDate = '2020-07-16 16:00:00'; 在这里,我得到了预期的结果,endDate ='2020-07-16 16:30:00'; 如果 insertDate 时间戳超出工作时间窗口,例如 if case2: insertDate = '2020-07-16 16:50:00'; 在这里,我没有得到预期的结果,应该是 endDate ='2020-07-17 08:20:00';对于周末(周六至周日),在该周末窗口创建的任何工单,应从周一 08:00:00 开始计算 case3: insertDate = '2020-07-18 16:50:00'; 在这里,我没有得到预期的结果,应该是 endDate ='2020-07-20 08:30:00';下面是我的代码,适用于 case1 很好,ubt 则适用于 case2 和 case3,对此的任何帮助都非常感谢。<?phpfunction calculateSLA($totalMinutes){$insertDate = '2020-07-16 16:00:00';$endDate = date('Y-m-d H:00:00',strtotime($insertDate)); //$t_min = date('i',strtotime($insertDate));$BusinessStart = '08:00:00';$BusinessEnd   = '17:00:00';$i           = 1;$flag        = false;while ($totalMinutes > 0) {    $day = date('D', strtotime($endDate)); // fetching day of week    if ($day == 'Sat') { // checking if saturday thenskip by adding 2 day to end date        $endDate = date('Y-m-d', strtotime($endDate . " +2 Day")) . ' ' . $BusinessStart; // adding 2 day if saturday        continue;    }    $diff  = strtotime($BusinessEnd) - strtotime(date("H:i:s", strtotime($insertDate))); // getting difference of time of office end date and result end date    var_dump($diff);    $mins = $diff / (60); // difference in mins.    if ($mins > $totalMinutes) {        $mins = $totalMinutes;        $flag  = true;     } else {        $mins = $totalMinutes - $mins; // substracting mins from total minutes left            }    $endDate = date('Y-m-d H:i:s', strtotime("+$mins Minute", strtotime($insertDate))); // adding subtracted minutes    if (!$flag) {        $endDate = date('Y-m-d', strtotime($insertDate . " +1 Day")) . ' ' . $BusinessStart; // if not last loop add day to result end date    } else {        break;    }}echo $endDate;}calculateSLA(30);?>
查看完整描述

1 回答

?
慕田峪4524236

TA贡献1875条经验 获得超5个赞

我将发布我的函数版本。您传递票证提交的日期时间并获取允许响应的日期时间。


function calculateSLA(DateTime $reportDate): DateTime {

  $responseDate = (clone $reportDate);


  // check conditions and add 1 minute to provided date 30 times (so 30 minutes)

  for($i=0; $i<30;$i++) {

    // if time is before 8:00 (working hours) skip to 8:00

    if ($responseDate->format('G') < 8) {

      $responseDate->setTime(8, 0);

    }


    // if time is after 17:00 (working hours) skip to next day at 8:00

    if ($responseDate->format('G') >= 17) {

      $responseDate->add(new DateInterval('PT15H'));

      $responseDate->setTime(8, 0);

    }


    // if at any time it is weekend skip to monday at 8:00

    if (in_array($responseDate->format('D'), ['Sat', 'Sun'])) {

      $responseDate = $responseDate->modify('next monday 8:00');

    }


    $responseDate->add(new DateInterval('PT1M'));

  }


  return $responseDate;

}

我用来在不同条件下测试这个函数的代码:


function test(string $date, string $expected) {

  $result = calculateSLA(new DateTime($date));

  echo 'date: '.$date.', expected: '.$expected.', got: '.$result->format('Y-m-d H:i:s').' '.($result->format('Y-m-d H:i:s') === $expected ? 'OK' : 'ERRROR').PHP_EOL;

}

test('2020-07-16 16:00:00', '2020-07-16 16:30:00'); // weekday during hours

test('2020-07-16 16:50:00', '2020-07-17 08:20:00'); // weekday during hours until next day

test('2020-07-18 16:50:00', '2020-07-20 08:30:00'); // weekend

test('2020-07-16 06:50:00', '2020-07-16 08:30:00'); // weekday before working hours

test('2020-07-16 20:50:00', '2020-07-17 08:30:00'); // weekday after working hours

test('2020-07-17 16:50:00', '2020-07-20 08:20:00'); // friday during working hours until monday

test('2020-07-17 17:50:00', '2020-07-20 08:30:00'); // friday after hours

输出:


date: 2020-07-16 16:00:00, expected: 2020-07-16 16:30:00, got: 2020-07-16 16:30:00 OK

date: 2020-07-16 16:50:00, expected: 2020-07-17 08:20:00, got: 2020-07-17 08:20:00 OK

date: 2020-07-18 16:50:00, expected: 2020-07-20 08:30:00, got: 2020-07-20 08:30:00 OK

date: 2020-07-16 06:50:00, expected: 2020-07-16 08:30:00, got: 2020-07-16 08:30:00 OK

date: 2020-07-16 20:50:00, expected: 2020-07-17 08:30:00, got: 2020-07-17 08:30:00 OK

date: 2020-07-17 16:50:00, expected: 2020-07-20 08:20:00, got: 2020-07-20 08:20:00 OK

date: 2020-07-17 17:50:00, expected: 2020-07-20 08:30:00, got: 2020-07-20 08:30:00 OK

棘手的部分是星期五,您没有真正提到,但我为其添加了测试用例。


查看完整回答
反对 回复 2023-08-11
  • 1 回答
  • 0 关注
  • 105 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信