0

私は、私たちの組織でボランティアをするために時間ブロックを予約したい人々から作成された配列を持っています. 重複する同じ日の時間ブロックを選択したかどうかを確認したい。以下の例の配列では、1 番目と 3 番目の要素が重複しているため、それを検出する必要があります。任意の推奨事項をいただければ幸いです。

 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

巨大な配列にはお勧めしませんが、ここに簡単な解決策があります。比較のために時刻を 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 に答える