[英]PHP : Select overlapping date time ranges with time range overlapping day
I would like to know how to get date time ranges overlapping other date time ranges. 我想知道如何获取与其他日期时间范围重叠的日期时间范围。 The particularity is that a date range can have time range overlapping two consecutive days. 特殊之处在于,日期范围的时间范围可以连续两天重叠。
For example i have a recurrent reservation the 01/01 and 02/01 beginning at 20:00 and finishing the next day at 02:00. 例如,我有一个经常性的预订01/01和02/01,从20:00开始,第二天在02:00结束。
First day: 第一天:
$start = '2017-01-01 20:00';
$end = '2017-01-02 02:00';
Second day: 第二天:
$start = '2017-01-02 20:00';
$end = '2017-01-03 02:00';
Now i would like to know how to get reservations overlapping this reservation. 现在,我想知道如何获取与此预订重叠的预订。
Note: All reservations can have or not time range overlapping day. 注意:所有预订的日期都可以重叠或不重叠。
For example from a PHP point of view i have the following reservations : Dates and times are represented here as string for readability. 例如,从PHP的角度来看,我有以下保留:为了便于阅读,日期和时间在此表示为字符串。 In reality they are DateTime. 实际上,它们是DateTime。
//The reservation
$reservation= array(
array(
'day' => '2017-01-01',
'time_range' => array('20:00', '23:59')
),
array(
'day' => '2017-01-02',
'time_range' => array('00:00', '02:00')
),
);
//Other reservations
$reservations= array(
//Reservation doesn't overlap
array(
'day' => '2017-01-01',
'time_range' => array('18:00', '19:00')
),
//Reservation overlaps
array(
'day' => '2017-01-01',
'time_range' => array('21:00', '22:00')
),
//Reservation overlaps
array(
array(
'day' => '2017-01-01',
'time_range' => array('23:00', '23:59')
),
array(
'day' => '2017-01-02',
'time_range' => array('00:00', '01:00')
),
),
...
);
Thanks! 谢谢!
First, you really should simplify your structure. 首先,您确实应该简化结构。 If you really DO have dateTimes everywhere, then reservations should look something more like: 如果您确实确实到处都有dateTimes,那么保留应该看起来更像:
class Reservation
{
/** @var DateTime $start */
public $start;
/** @var DateTime $stop */
public $stop;
public function _construct(DateTime $start, DateTime $stop): void
{
$this->start = $start;
$this->stop = $stop;
}
public function isOverlapping(Reservation $reservation): bool
{
if ($reservation->start >= $this->start && $reservation->start <= $this->stop) {
// starts during reservation
return true;
}
if ($reservation->stop >= $this->start && $reservation->stop <= $this->stop) {
// ends during reservation
return true;
}
if ($reservation->start <= $this->start && $reservation->end >= $this->stop) {
// $this is contained by $reservation
return true;
}
return false;
}
}
Structuring your reservations this way will allow for some very simple solutions to your problem, like creating RecurringReservation
which can generate an array of Reservations
for a given date-range. 通过这种方式来构造您的预订,将为您的问题提供一些非常简单的解决方案,例如创建RecurringReservation
,它可以为给定的日期范围生成一系列的Reservations
。 Or a Reservation->isToday()
method which could check the $start
and $stop
properties in cases where it wraps midnight. 或者是Reservation->isToday()
方法,它可以在午夜$start
检查$start
和$stop
属性。
class Reservation
{
. . .
public function anyOverlap(array $reservations): bool
{
foreach ($reservations as $checkMe) {
if ($this->isOverlapping($checkMe)) {
return true;
}
}
return false;
}
}
$reservation = new Reservation(new DateTime('2017-01-01 20:00'), new DateTime('2017-01-02 02:00'));
$reservations = [
new Reservation(new DateTime('2017-01-01 18:00'), new DateTime('2017-01-01 19:00')),
new Reservation(new DateTime('2017-01-01 21:00'), new DateTime('2017-01-01 22:00')),
new Reservation(new DateTime('2017-01-01 23:00'), new DateTime('2017-01-02 01:00')),
];
$reservation->anyOverlap($reservations); // true
class Reservation
{
. . .
public function getOverlapping(array $reservations): array
{
$result = [];
foreach ($reservations as $checkMe) {
if ($this->isOverlapping($checkMe)) {
$result[] = $checkMe;
}
}
return $result;
}
}
. . .
$overlapping = $reservation->getOverlapping($reservations); // array
Generators are awesome (when not misused). 生成器很棒(不被滥用时)。 They offer very high performance when you need a list of results. 当您需要结果列表时,它们可以提供非常高的性能。 They're only catch is that you have to pass their result straight into a loop to reap the benefits. 他们唯一能抓住的是,您必须将其结果直接传递到循环中才能获得好处。
public function getOverlapping(array $reservations): Generator
{
foreach ($reservations as $checkMe) {
if ($this->isOverlapping($checkMe)) {
yield $checkMe;
}
}
}
...
foreach($reservation->getOverlapping($reservations) as $overlap) {
yellAtReceptionistFor($overlap); // ... or whatever
}
You want to test an appointment start is between the other appointment start and end, then same for the appointment end. 您要测试约会开始在另一个约会开始和结束之间,然后对约会结束进行相同的测试。 If either is true, you have an overlap. 如果任何一个为真,则您有一个重叠。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.