希望你做得很棒!!
我有点坚持这一点,我所做的只有在没有重叠的情况下才能工作,无论如何我不确定这是正确的做法。
所以我当前的实现是将所有时间合并(start_time和end_time作为该数组中的不同条目),对它们进行排序并删除重复项(如果有的话)。
然后我循环进入该列表并检查它们是否在$ times范围内而不在限制范围内。
所有通过这些条件的人都被添加到另一个列表中。然后最后我将循环遍历该列表'一次2项'并构建最终的时间范围数组。
代码:https://3v4l.org/2elDs(Laravel,使用Collection和Carbon,所以不会在那里运行)
没有日期/时间重叠的示例:
$times = [
[
'start_time' => '2017-06-26 00:00:00',
'end_time' => '2017-06-26 05:00:00',
],
[
'start_time' => '2017-06-26 13:00:00',
'end_time' => '2017-06-26 18:00:00',
]
];
$timesToExclude= [
[
'start_time' => '2017-06-26 04:00:00',
'end_time' => '2017-06-26 04:30:00',
],
[
'start_time' => '2017-06-26 07:00:00',
'end_time' => '2017-06-26 10:00:00',
],
[
'start_time' => '2017-06-26 15:00:00',
'end_time' => '2017-06-26 16:00:00',
]
];
结果:
$result = [
[
"start_time" => "2017-06-26 00:00:00",
"end_time" => "2017-06-26 04:00:00"
], [
"start_time" => "2017-06-26 04:30:00",
"end_time" => "2017-06-26 05:00:00"
],
[
"start_time" => "2017-06-26 13:00:00",
"end_time" => "2017-06-26 15:00:00"
],
[
"start_time" => "2017-06-26 16:00:00",
"end_time" => "2017-06-26 18:00:00"
]
]
日期/时间重叠的样本
$times = [
[
'start_time' => '2017-06-26 00:00:00',
'end_time' => '2017-06-26 10:00:00',
],
[
'start_time' => '2017-06-26 05:00:00',
'end_time' => '2017-06-26 20:00:00',
]
];
$timesToExclude= [
[
'start_time' => '2017-06-26 04:00:00',
'end_time' => '2017-06-26 04:30:00',
],
[
'start_time' => '2017-06-26 07:00:00',
'end_time' => '2017-06-26 09:00:00',
],
[
'start_time' => '2017-06-26 15:00:00',
'end_time' => '2017-06-26 16:00:00',
]
];
应该导致:
$result = [
[
"start_time" => "2017-06-26 00:00:00",
"end_time" => "2017-06-26 04:00:00"
], [
"start_time" => "2017-06-26 04:30:00",
"end_time" => "2017-06-26 05:00:00"
],
[
"start_time" => "2017-06-26 05:00:00",
"end_time" => "2017-06-26 07:00:00"
],
[
"start_time" => "2017-06-26 09:00:00",
"end_time" => "2017-06-26 10:00:00"
],
[
"start_time" => "2017-06-26 10:00:00",
"end_time" => "2017-06-26 15:00:00"
],
[
"start_time" => "2017-06-26 16:00:00",
"end_time" => "2017-06-26 20:00:00"
]
]
任何人都知道正确的算法/伪处理吗?
答案 0 :(得分:0)
创建对{time; flag}
的公共列表,其中flag为time_start, time_end, restriction_start or restriction_end
。
按时间对此列表进行排序。如果领带使用标志为辅助密钥(例如,restr_start
应该在time_end
之后)。
制作$Active=0
,$Exclude=0
浏览排序列表。
当您遇到time_start
时,会增加$Active
{1}
当您遇到time_end
时,会减少$Active
{2}
当您遇到restriction_start
时,会增加$Exclude
{3}
当您遇到restriction_end
时,会减少$Exclude
{4}
在下一种情况下打开输出间隔:
{1}:$Active
变为1和$Exclude = 0
{4}:$Exclude becomes 0
和$Active
非零
在下一种情况下关闭输出间隔:
{2} $Active
变为0和$Exclude = 0
{3} $Exclude becomes 1
和$Active
非零
示例:(不知道复杂条件下的确切php语法)
case $TimeStart:
$active = $active + 1;
if ($active=1) and ($exclude=0)
$range['start_time'] = $mergedTime['time'];
break;
....
case $RestrictionEnd:
$exclude = $exclude - 1;
if ($exclude=0) and ($active > 0)
$range['start_time'] = $mergedTime['time'];
break;
答案 1 :(得分:0)
function excludeOverlaping($disponibilities,$plages) {
if(count($disponibilities) == 0)
return $disponibilities;
if(count($plages) == 0)
return $disponibilities;
usort($disponibilities, function($a, $b)
{
return strtotime($a->startDate) - strtotime($b->startDate);
});
usort($plages, function($a, $b)
{
return strtotime($a->startDate) - strtotime($b->startDate);
});
for($i = 0; $i < count($disponibilities); $i++){
for($j=0;$j<count($plages);$j++){
$dispo = $disponibilities[$i];
if(isset($dispo->exclude)){
break;
}
$plage = $plages[$j];
if(strtotime($dispo->startDate)>=strtotime($plage->startDate) && strtotime($dispo->endDate)<=strtotime($plage->endDate)){
$disponibilities[$i]->exclude = true;
}else if( strtotime($dispo->startDate)<strtotime($plage->startDate) && strtotime($dispo->endDate) <= strtotime($plage->endDate) && strtotime($dispo->endDate) > strtotime($plage->startDate)){
$disponibilities[$i]->endDate = $plage->startDate;
}else if( strtotime($dispo->startDate)>=strtotime($plage->startDate) && strtotime($dispo->startDate)<=strtotime($plage->endDate) && strtotime($dispo->endDate) > strtotime($plage->endDate)){
$disponibilities[$i]->startDate = $plage->endDate;
}else if( strtotime($dispo->startDate)<strtotime($plage->startDate) && strtotime($dispo->endDate) > strtotime($plage->endDate) ){
echo "[[[4]]]\n";
$tmp = new stdClass();
$tmp->startDate = $dispo->startDate;
$tmp->endDate = $plage->startDate;
$tmp2 = new stdClass();
$tmp2->startDate = $plage->endDate;
$tmp2->endDate = $dispo->endDate;
$disponibilities[$i]->exclude = true;
array_push($disponibilities,$tmp);
array_push($disponibilities,$tmp2);
}
}
}
for($i=0;$i<count($disponibilities);$i++){
if(isset($disponibilities[$i]->exclude)){
array_splice($disponibilities,$i,1);
$i--;
}
}
var_dump($disponibilities);
}
$times = array();
$restrictions = array();
$obj = new stdClass();
$obj->startDate = '2017-06-26 00:00:00';
$obj->endDate = '2017-06-26 07:00:00';
array_push($times,$obj);
$obj = new stdClass();
$obj->startDate = '2017-06-26 00:00:00';
$obj->endDate = '2017-06-26 24:00:00';
array_push($times,$obj);
$obj = new stdClass();
$obj->startDate = '2017-06-26 04:00:00';
$obj->endDate = '2017-06-26 06:00:00';
array_push($restrictions,$obj);
$obj = new stdClass();
$obj->startDate = '2017-06-26 00:00:00' ;
$obj->endDate = '2017-06-26 01:00:00';
array_push($restrictions,$obj);
excludeOverlaping($times,$restrictions);