2 回答
TA贡献1811条经验 获得超4个赞
以下功能应该做到这一点(如果我没有错过任何东西)。对于每个活动,它会遍历所有空闲范围,检查活动是否重叠并相应地调整/创建新范围。
请注意,理想情况下,您的“句点”条目应该是对象(具有start和end作为DateTime属性),以便为函数提供更强的签名/减少多余代码的数量。
function getFreeTimeRanges(array $fullRange, array $activities): array
{
$freeRanges = [[
'start' => new \DateTime($fullRange['start']),
'end' => new \DateTime($fullRange['end'])
]];
foreach ($activities as $activity) {
$activityStart = new \DateTime($activity['start']);
$activityEnd = new \DateTime($activity['end']);
foreach ($freeRanges as &$range) {
$activityIsOverlapping = $activityStart < $range['end']
&& $activityEnd > $range['start'];
if ($activityIsOverlapping) {
$activityStartsLater = $activityStart > $range['start'];
$activityEndsBefore = $activityEnd < $range['end'];
if ($activityStartsLater) {
if ($activityEndsBefore) {
$freeRanges[] = [
'start' => $activityEnd->modify('+1 second'),
'end' => $range['end']
];
}
$range['end'] = $activityStart->modify('-1 second');
}
elseif ($activityEndsBefore) {
$range['start'] = $activityEnd->modify('+1 second');
}
}
}
}
uasort($freeRanges, static function (array $range1, array $range2) {
return $range1['start'] <=> $range2['start'];
});
return array_map(static function ($range) {
return [
'start' => $range['start']->format('Y-m-d H:i:s'),
'end' => $range['end']->format('Y-m-d H:i:s')
];
}, $freeRanges);
}
$fullRange = ['start' => '2019-12-01 00:00:00', 'end' => '2019-12-31 23:59:59'];
$activities = [
0 => ['start' => '2019-12-08 09:00:00', 'end' => '2019-12-08 10:00:00'],
1 => ['start' => '2019-12-07 09:00:00', 'end' => '2019-12-07 17:40:00'],
2 => ['start' => '2019-12-10 10:00:00', 'end' => '2019-12-15 17:00:00'],
3 => ['start' => '2019-12-11 08:00:00', 'end' => '2019-12-17 21:00:00'],
4 => ['start' => '2019-12-08 08:57:05', 'end' => '2019-12-08 19:00:00'],
5 => ['start' => '2019-12-04 10:00:00', 'end' => '2019-12-05 17:00:00'],
6 => ['start' => '2019-12-20 10:00:00', 'end' => '2019-12-31 23:59:59'],
7 => ['start' => '2019-12-16 10:00:00', 'end' => '2019-12-31 23:59:59']
];
print_r(getFreeTimeRanges($fullRange, $activities));
演示:https ://3v4l.org/p8Kvl
TA贡献1828条经验 获得超4个赞
这可能适用于所有情况:
foreach ( $array_activities as $index_1 => $array_activity ) {
foreach ($result as $index_2 => $r) {
if ( $r['start'] < $array_activity['start'] && $array_activity['start'] < $r['end'] ) {
$temp = new Datetime($array_activity['start']);
$temp->modify("-1 second");
$result[$index_2]['end'] = $temp->format("Y-m-d H:i:s");
if ( $r['start'] < $array_activity['end'] && $array_activity['end'] < $r['end'] ) {
$result[] = array("start" => $array_activity['start'], "end" => $r['end']);
}
} else {
if ( $array_activity['start'] <= $r['start'] && $array_activity['end'] >= $r['end'] ) {
unset($result[$index_2]);
}
}
}
foreach ($result as $index_2 => $r) {
if ( $r['start'] < $array_activity['end'] && $array_activity['end'] < $r['end'] ) {
$temp = new Datetime($array_activity['end']);
$temp->modify("+1 second");
$result[$index_2]['start'] = $temp->format("Y-m-d H:i:s");
$result[$index_2]['end'] = $r['end'];
}
}
echo '<pre>';
var_dump($result);
echo '</pre>';
}
- 2 回答
- 0 关注
- 104 浏览
添加回答
举报