📅  最后修改于: 2023-12-03 14:53:11.468000             🧑  作者: Mango
在很多应用中,需要对时间进行操作和验证,其中一个常见的需求就是检查是否有时间重叠的情况。本文将介绍如何在 PHP 中实现时间重叠的检查。
为方便起见,我们先给出一个示例的数据结构,假设我们有一个数据库表格 events
,其中每一行表示一个活动,有如下列:
id
:活动的唯一标识符(整数类型);start_time
:活动的开始时间(UNIX 时间戳);end_time
:活动的结束时间(UNIX 时间戳)。CREATE TABLE `events` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`start_time` int(11) NOT NULL,
`end_time` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
检查时间重叠可以归结为以下几个步骤:
/**
* 判断给定的活动是否与已有的活动有时间重叠
*
* @param array $eventList 已有的活动列表,每个元素包括 id、start_time、end_time 三个字段
* @param array $event 要新增的活动,包括 start_time 和 end_time 两个字段
* @return bool 返回是否存在时间重叠
*/
function isOverlapping(array $eventList, array $event)
{
// 先将已有的活动按开始时间升序排序
usort($eventList, function ($a, $b) {
return $a['start_time'] - $b['start_time'];
});
// 遍历已有的活动列表,与要新增的活动比较
foreach ($eventList as $existingEvent) {
if ($event['start_time'] > $existingEvent['end_time']) {
// 当前活动的开始时间晚于前一个活动的结束时间,没有重叠,继续遍历
} elseif ($event['end_time'] < $existingEvent['start_time']) {
// 当前活动的结束时间早于后一个活动的开始时间,没有重叠,继续遍历
} else {
// 发现重叠,直接返回 true
return true;
}
}
// 遍历完所有已有的活动,没有发现重叠,返回 false
return false;
}
我们定义了一个 isOverlapping
函数,它接受一个已有的活动列表和一个待新增的活动,返回是否存在时间重叠。函数内部使用了 PHP 的排序函数 usort
对已有的活动按开始时间排序,并使用一次简单的遍历判断时间是否重叠。如果发现重叠,直接返回 true
,不必再继续遍历。
以下是一些测试样例,它们分别表示在不同条件下的时间重叠情况:
$eventList = [
['id' => 1, 'start_time' => 1609459200, 'end_time' => 1609473600], // 2021-01-01 00:00:00 - 2021-01-01 04:00:00
['id' => 2, 'start_time' => 1609466400, 'end_time' => 1609480800], // 2021-01-01 02:00:00 - 2021-01-01 06:00:00(与前一个活动有重叠)
['id' => 3, 'start_time' => 1609473600, 'end_time' => 1609488000], // 2021-01-01 04:00:00 - 2021-01-01 08:00:00(与前一个活动有重叠,与后一个活动无重叠)
['id' => 4, 'start_time' => 1609495800, 'end_time' => 1609506600], // 2021-01-01 10:50:00 - 2021-01-01 13:10:00(与前一个活动无重叠)
];
$eventToAdd = ['start_time' => 1609462800, 'end_time' => 1609470000]; // 2021-01-01 01:00:00 - 2021-01-01 03:00:00(与已有的活动有重叠)
var_dump(isOverlapping($eventList, $eventToAdd)); // true
$eventToAdd = ['start_time' => 1609488000, 'end_time' => 1609491600]; // 2021-01-01 08:00:00 - 2021-01-01 09:00:00(与已有的活动无重叠)
var_dump(isOverlapping($eventList, $eventToAdd)); // false
我们可以通过调用 isOverlapping
函数,传入不同的测试样例进行验证。在上面的测试样例中,第一次调用 isOverlapping
传入的是一个与已有的活动有时间重叠的活动,第二次调用传入的是一个与已有的活动没有时间重叠的活动。期望的结果是第一次调用返回 true
,第二次调用返回 false
。