排除日期/时间范围与重叠的日期/时间范围

问题描述:

希望你做得很好!排除日期/时间范围与重叠的日期/时间范围

我有点卡住这个,我所做的只有在没有重叠的情况下才能工作,无论如何我都不确定这是正确的方法。

所以我当前的实现是合并所有时间(start_time和end_time作为该数组中的不同条目),对它们进行排序并删除重复项(如果有的话)。

然后我循环进入该列表并检查它们是否在$ times范围内而不在限制范围内。

所有通过这些条件的人都被添加到另一个列表中。然后,最后,我将循环访问该列表'一次2项',并构建最终的时间范围数组。

代码:https://3v4l.org/2elDs(Laravel,使用收集和碳,所以不会出现运行)

样品没有日期/时间重叠:

$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

你的例子对我没有意义。我只看了第一个。输入5个数组,输出4.我可以理解你提到的重复。但时代正在转移。为什么? 00-05变成00-04。 04-04:30我搬走了,也改变了。我不明白你需要以不同的方式验证或解释你的输入/输出。 – Andreas

+0

@Andreas $ times是我最初的次数列表,$ timesToExclude是我需要从最初列表中排除的次数,只是将该变量重命名,是否有意义? – David

+0

我明白你的意思了。让我想一会儿。 – Andreas

创建配对{time; 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,增量值​​{3}

当您遇到restriction_end时,递减值为​​{4}

Op烯在下一情况下,输出时间间隔:
{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; 
+0

嗨@MBo,不确定我得到(正值+1,负值-1),你能解释吗? – David

+0

好吧,认为我得到了绝对的东西,但不是最后一部分'当$ Active变为正值时开始输出间隔,并以其他方式结束(0或负值)' – David

+0

也许你可以看看? https://3v4l.org/oEbRk – David