返回不包括"非工作时间"的日期之间的平均时差



我正在为我的公司制作一个票务系统。在我的数据库中,我记录了首次提出工单时的时间戳和工单标记为已完成时的时间戳。

我写了一个函数,它返回完成票证所需的平均时间(小时(:

public function calculateAvgResolveTime()
{
$timeQuery = $this->database->query('SELECT ticketCreated, ticketCompletedOn FROM employeeTickets');
$cumulativeTicketTime = $cumulativeTimes = 0;
while($time = $timeQuery->fetch_assoc()) {
$timeCreated = strtotime($time['ticketCreated']);
$timeCompleted = strtotime($time['ticketCompletedOn']);
if($timeCompleted > $timeCreated) {
$cumulativeTimes++;
$cumulativeTicketTime = $cumulativeTicketTime + ($timeCompleted - $timeCreated);
}
}
$time = ($cumulativeTicketTime / 60 / 60);
$time = sprintf('%02d:%02d', (int) $time, round(fmod($time, 1) * 60));
return $time;
}

有没有办法排除某些时间?例如,我们的办公室开放时间为周一至周五的09:00-17:00。

目前,如果一张票在周五 16:30 提出,并在周一 09:15 完成,那么平均时间会相当高,而实际上这张票只花了 45 分钟的工作时间。

var_export()结果:

array(
array ( 'ticketCreated' => '2020-02-03 15:59:30','ticketCompletedOn' => '2020-02-04 09:53:35'),
array ( 'ticketCreated' => '2020-02-04 14:00:00', 'ticketCompletedOn' => '2020-02-04 14:36:00')
)

您将不得不每天循环ticketCreatedticketCompletedOn之间的日期。 似乎没有数学方法(或至少不是可读的格式(来解决这个问题,因为您有排除星期六和星期日的时间限制以及从09:00:0017:00:00的工作期限。

片段:

<?php
$data =array(
array ( 'ticketCreated' => '2020-02-03 15:59:30','ticketCompletedOn' => '2020-02-04 09:53:35'),
array ( 'ticketCreated' => '2020-02-04 14:00:00', 'ticketCompletedOn' => '2020-02-04 14:36:00')
);
$sum_time = 0;
foreach($data as $details){
$start_time = new DateTime($details['ticketCreated']);
$end_time = new DateTime($details['ticketCompletedOn']);
$end_of_day = new DateTime($start_time->format('Y-m-d') . ' 17:00:00'); // since a day ends at 17:00
do{
$diff  = $end_time->diff($start_time);
$diff2 = $end_of_day->diff($start_time); 
if($end_time->format('Y-m-d') === $start_time->format('Y-m-d')){ // meaning finished on the same day
$sum_time += ($diff->h * 60) + ($diff->i) + ($diff->s / 60);
}else if(!in_array($end_of_day->format('N'),[6,7])){ // skipping Saturdays and Sundays
$sum_time += ($diff2->h * 60) + ($diff2->i) + ($diff2->s / 60); // add the day's offset(480 minutes)
}       
$end_of_day->add(new DateInterval('P1D'));
$start_time = new DateTime($end_of_day->format('Y-m-d') . ' 09:00:00'); // start time for next day which is 09:00
}while($start_time <= $end_time);
}

$avg = $sum_time / count($data);
echo "$avg minutes",PHP_EOL;

演示:https://3v4l.org/gpFt4

解释:

  • 我们首先创建日期的DateTime实例。
  • 我们现在在里面有一个 do while 循环。
  • 如果结束时间和开始时间是同一天,我们只是取小时、分钟和秒的差异。
  • 如果结束时间和开始时间不是在同一天,那么我们从start_time中减去时间end_of_day这将是 480 分钟,用于该天的正确开始或剩余偏移量,直到17:00:00点。
  • 如果我们遇到星期六或星期日的一天,我们就会跳过它。
  • 最后,我们只需通过将总和除以门票总数来打印平均值。

最新更新