我为不同的用户组创建了班次。该班次包括班次开始时间和结束时间,星期几(多选)和日期时间段(从日期到日期)适用。
特定用户的轮班选择是多项选择,因为一个用户可以在同一天或同一天的不同时间进行多次轮班。 那么,如何检查所选的班次是否与一个用户不能同时进行两个班次的方式重叠?
我尝试过首先检查工作日是否相交,如果工作日相交,则使用以下代码检查日期和时间段是否重叠,但未获得正确的结果。
/**
* @Route("/shift/checkTimeConflict", methods={"POST"})
*/
public function checkTimeConflict(Request $request)
{
$data = $request->request->all();
if (isset($data['shifts']) && count($data['shifts']) > 1) {
$shifts = $this->getDoctrine()
->getRepository(Shift::class)
->findById($data['shifts']);
foreach ($shifts as $key => $val) {
$shift_data[$key]['id'] = $val->getId();
$shift_data[$key]['title'] = $val->getTitle();
$shift_data[$key]['weekday'] = $val->getWeekday();
$shift_data[$key]['start_time'] = $val->getStartTime()->format('H:i');
$shift_data[$key]['end_time'] = $val->getEndTime()->format('H:i');
$shift_data[$key]['time_period_start'] = $val->getTimePeriodStart()->format('Y-m-d');
$shift_data[$key]['time_period_end'] = $val->getTimePeriodEnd()->format('Y-m-d');
}
for ($i=0; $i < count($shift_data); $i++) {
if ($this->checkDateTimeOverlaps($shift_data[$i], $shift_data))
return new JsonResponse(true);
}
}
return new JsonResponse(false);
}
/**
* Check provided shift time for the day and period overlaps with other shifts
*/
public function checkDateTimeOverlaps($shift, $shift_data)
{
$start = strtotime($shift['time_period_start'].' '.$shift['start_time']);
$end = strtotime($shift['time_period_end'].' '.$shift['end_time']);
for ($i=0; $i < count($shift_data); $i++) {
if ($shift['id'] != $shift_data[$i]['id']) {
$check_start = strtotime($shift['time_period_start'].' '.$shift['start_time']);
$check_end = strtotime($shift['time_period_end'].' '.$shift['end_time']);
if (!empty(array_intersect($shift['weekday'], $shift_data[$i]['weekday']))) {
if (($start > $check_start && $start < $check_end) || ($end > $check_start && $end < $check_end) || ($check_start > $start && $check_start < $end) || ($check_end > $start && $check_end < $end)) {
return true; // intersects
}
}
}
}
return false; // no conflict
}
例如,选定的班次具有以下数据:
(1) 09:00-13:00, Monday-Friday, 2019-01-01 - 2020-01-01, First-Half
(2) 14:00-18:00, Monday-Friday, 2019-01-01 - 2020-01-01, Second-Half
(3) 18:00-20:00, Monday-Friday, 2019-01-01 - 2020-01-01, Over-Time
(4) 09:00-14:00, Saturday, 2019-01-01 - 2020-01-01, Saturday Half Day
(5) 09:00-13:00, Monday-Friday, 2020-02-01 - 2021-02-28, Part-Time
上述内容不应返回任何冲突[checkDateTimeOverlaps()应该返回false],因为同一天和同一日期的时间段之间没有时间交叉。但是,如果我按如下所示替换第五行:
(5) 09:00-13:00, Monday-Friday, 2019-01-01 - 2019-01-31, Part-Time
它应该返回冲突[checkDateTimeOverlaps()应该返回true],因为一个人不能同时进行两次轮班。在上述情况下,第1行和第5行有一个交点。