0

我有一个数组,它是由希望保留时间段以自愿加入我们组织的人们制作的。我想看看他们是否在同一天选择了重叠的时间段。在我下面的示例数组中,第一个和第三个元素是重叠的,我需要检测到这一点。任何建议将不胜感激:

 Array
(
    [0] => Array
        (
            [id_pc_time_blocks] => 3
            [id_pc] => 2
            [pc_date] => 2012-11-21
            [pc_time_block] => 9:00 AM-1:00 PM
            [pc_time_block_max] => 25
            [pc_time_block_count] => 0
            [pc_name] => Atlanta
        )

    [1] => Array
        (
            [id_pc_time_blocks] => 4
            [id_pc] => 2
            [pc_date] => 2012-11-21
            [pc_time_block] => 1:00 PM-5:00 PM
            [pc_time_block_max] => 25
            [pc_time_block_count] => 10
            [pc_name] => Atlanta
        )

    [2] => Array
        (
            [id_pc_time_blocks] => 6
            [id_pc] => 2
            [pc_date] => 2012-11-21
            [pc_time_block] => 10:00 AM-2:00 PM
            [pc_time_block_max] => 25
            [pc_time_block_count] => 0
            [pc_name] => Atlanta
        )

       [3] => Array
        (
            [id_pc_time_blocks] => 6
            [id_pc] => 2
            [pc_date] => 2012-11-23
            [pc_time_block] => 10:00 AM-2:00 PM
            [pc_time_block_max] => 25
            [pc_time_block_count] => 0
            [pc_name] => Atlanta
        )

       [4] => Array
        (
            [id_pc_time_blocks] => 6
            [id_pc] => 2
            [pc_date] => 2012-11-23
            [pc_time_block] => 3:00 AM-6:00 PM
            [pc_time_block_max] => 25
            [pc_time_block_count] => 0
            [pc_name] => Atlanta
        )

)
4

3 回答 3

1

不推荐用于 HUGE 阵列,但这是一个快速的解决方案。您需要将 hte 时间分解为 unix 时间戳以进行比较

// Run down each element of the array. (I've called it MyStartArray)
$numElements = count($MyStartArray);
for ($i=0; $i<$numElements ; $i++) {

    // Calculate "Start Time" and "End Time" as Unix time stamps (use mktime function) and store as another items in the array
    // You can use preg_match or substr to get the values to pump into mktime() below - not writing hte whole thing for you ;)
    $MyStartArray[$i]['start_time'] = mktime( ... );
    $MyStartArray[$i]['end_time'] = mktime( ... );

    // Now run through all the previous elements to see if a start time is before the end time, or an end time is after the start time.
    if ($i > 0) {
        for ($j=0; $j<$i;$j++) {
            if ($MyStartArray[$i]['start_time'] < $MyStartArray[$j]['end_time'] ||
                  $MyStartArray[$j]['end_time'] > $MyStartArray[$j]['start_time'] ) {
                     echo 'CLASH';
            }
        }
    }
}
于 2012-05-23T13:30:27.290 回答
0

这是我检查每个日期是否有重叠时间的解决方案。唯一的事情是,这是针对我的特定情况的,并且不考虑重叠年份,因为我不需要此应用程序。

这是我的工作示例:

$dateIdx = 0;
    foreach($timeblocks_array as $obj) {
           $timeblocks_array[$dateIdx]["intDay"] = idate("z",strtotime($obj["pc_date"]));
           $timeblocks_array[$dateIdx]["intStart"] = intval($obj["start_time"]);
           $timeblocks_array[$dateIdx]["intEnd"] = intval($obj["end_time"]);
           $mindates[] = idate("z",strtotime($obj["pc_date"]));
           $dateIdx++;
    }
    $minDateSingle = min($mindates);
    $maxDateSingle = max($mindates);

    $currentDate = $minDateSingle;
    $dateIdx = 0;
    while ($currentDate <= $maxDateSingle) {
           $hrIndex = 0;
           while ($hrIndex < 24) {
                  $matrixArray[$dateIdx][$hrIndex]["count"] = 0;
                  $matrixArray[$dateIdx][$hrIndex]["intDay"] = $currentDate;
                  $hrIndex++;         
           }
           // calculate counts:
           $hourIdx = 0;
           foreach($matrixArray[$dateIdx] as $hour){
                  foreach($timeblocks_array as $block) {
                         if ($hour["intDay"] == $block["intDay"]) {
                               if ($hourIdx >= $block["intStart"] && $hourIdx < $block["intEnd"]) {
                                      $matrixArray[$dateIdx][$hourIdx]["count"] = $matrixArray[$dateIdx][$hourIdx]["count"] + 1;
                                      $matrixArray[$dateIdx][$hourIdx]["requests"][] = $block;
                               }
                         }
                  }
                  $hourIdx++;
           }
           $dateIdx++;
           $currentDate = $currentDate + 1; 
    }

    //loop through the matrix array and timeblocks array to see if they intersect
    foreach($matrixArray as $day) {
           $hourIdx = 0;
           foreach($day as $hour) {
                  if ($hour["count"] > 1) {
                         //echo $hour["intDay"]." - Overlap on Hour $hourIdx\n";
                         $smarty->assign('overlappingError', 1);
                         $error = 1;
                         foreach($hour["requests"] as $overlapblock) {
                               //echo " --> conflict: ". $overlapblock["pc_date"]." ".$overlapblock["pc_time_block"]." (".$overlapblock["intStart"]." to ".$overlapblock["intEnd"].")\n";
                         }
                  } else if ($hour["count"] == 1) {
                         // these are valid hours
                  }     
                  $hourIdx++;
           }     
    }   
于 2012-06-14T19:46:45.280 回答
0

罗比的回答对我不起作用。我发现在他的示例中,仅针对日期需要制定的规则是:

$i[start] 需要小于且不等于 $i[stop]

$i[start] 需要大于且不等于 $j[stop]

$j[start] 需要小于且不等于 $j[stop]

因此我的解决方案是:

$numElements = count($dates);

for ($i=0; $i<$numElements; $i++) {

    $dates[$i]['start_time'] = strtotime($dates[$i]['start']);
    $dates[$i]['end_time'] = strtotime($dates[$i]['end']);

    if ($i > 0) {

        for ($j=0; $j<$i;$j++) {

            if($dates[$i]['start_time'] >= $dates[$i]['end_time'] || $dates[$i]['start_time'] <= $dates[$j]['end_time'] || $dates[$j]['start_time'] >= $dates[$j]['end_time']) {
                $this->set_error(['dates_overlap']);
                $this->dates_overlap = true;
                break;
            }

        }
    }

    if(isset($this->dates_overlap))
        break;
}
于 2012-07-06T09:43:38.473 回答