2011-12-07 12 views
1

これで、複数の項目に対して開始日時と終了日時が設定されています。お互いに同じ日時の中に3つ以上のアイテムがあるかどうかを調べる必要があります。私はちょうど私がこの機能を使用して配列に、個々の項目の日数を取得することができ、この1のまわりで私の頭をラップすることはできません複数の日付範囲をチェックして、同じ日が3回以上あるかどうかを調べる必要があります。

function getDatesBetween2Dates($startTime, $endTime) { 
$day = 86400; 
$format = 'm/d/y g:i A'; 
$startTime = strtotime($startTime); 
$endTime = strtotime($endTime); 
$numDays = round(($endTime - $startTime)/$day) + 1; 
$days = array(); 
for ($i = 0; $i < $numDays; $i++) { 
    $days[] = date($format, ($startTime + ($i * $day))); 
} 
return $days; 
} 
問題がある

は、それだけで最初の時間を取得し、ちょうど丸一日が追加されますその後は毎日です。最後の日の時間は考慮されません。私はこれを行う効率的な方法を考えることができません。

明確にするために、例を挙げておきます。私は自分のテーブルに5つのアイテムを持っています、彼らはそれぞれdatetime range ... startとendを持っています。私は、それらのアイテムのうちの4つ以上のアイテムが同じ日付範囲内にあるかどうかをチェックする必要があります。誰かが私を正しい方向に向けることができますか?ありがとう。

+0

forループにif文を追加して、最後の日であるかどうかを確認することで、最後の日の時刻を取得することができました。 – John

答えて

1

for ($i = 0; $i < $numDays; $i++) {からfor ($i = 0; $i <= $numDays; $i++) {に変更すると、最後の日付を含む範囲内のすべての日付が取得されます。

残念ながら、これは間違った方向に向かっています。ここで私はそれを行うだろうかのいくつかの擬似コードです:

Iterate through the list of date ranges 
    Log the earliest start date 
    Log the last end date 

Iterate through all dates between the earliest start date and the last end date 
    Iterate through the list of date ranges, to determine how many date ranges contain the current date 
     If more than three date ranges contain the current date, then store it in an array of conflicting dates 

私は、これが最も効率的な方法であるとは思わないが、あなたは巨大な日付範囲や日付の非常に大きい数を扱っている場合を除き、それはなります比較的速い。

+0

ありがとう、実際には意味があります。 – John

1

これはおそらく何か?

  • アイテムで最新の終了日まで、最も早い開始日から延びる日付のリストを作成します

  • 反復その範囲内のすべての日付に

  • それぞれを各アイテムのIDを追加する項目を超えますリストの日付には、その日付が範囲に含まれるアイテムのIDのセットが追加されました。
  • 各日付に対するアイテムの数をカウントします。いずれかが4つの以上のIDを持っている場合は、あなたの状態は、「私のテーブルに」

`

class Item { 
    private static $next_id = 0; 
    public $id; 
    public $start, $end; 

    public function __construct($start, $end) { 
    $this->id = self::$next_id++; 
    $this->start = $start; 
    $this->end = $end; 
    } 
} 

$items = array(
    new Item('06-Dec-2011', '12-Dec-2011'), 
    new Item('01-Dec-2011', '04-Dec-2011'), 
    new Item('02-Dec-2011', '07-Dec-2011'), 
    new Item('07-Dec-2011', '09-Dec-2011'), 
    new Item('06-Dec-2011', '10-Dec-2011'), 
); 

foreach ($items as $item) { 
    $start = strtotime($item->start); 
    $end = strtotime($item->end); 
    for ($day = $start; $day <= $end; $day += 24 * 60 * 60) { 
    $dates[$day][] = $item->id; 
    } 
} 

foreach ($dates as $day => $ids) { 
    $count = sizeof($ids); 
    if ($count > 3) { 
    echo $count, " items found on ", date('d-M-Y', $day), "\n"; 
    foreach ($ids as $id) { 
     echo " Item ", $id, "\n"; 
    } 
    } 
} 
1

真である - そして自分自身に多くの痛みを保存して、あなたのためにそれらを見つけるために、DBをお願いします。それはずっと簡単でずっと速くなるでしょう。

"同じ日時の中にある"という意味はわかりません。

同じ暦日ですか?同じ週の日ですか?同じ24時間ですか?同じ時間にデータの解像度の精度(通常は秒)ですか?他に何か?あなたのコードは、明示的なイベントではなく、重複する範囲を実際に探していることを示唆しています。

だから、のようなもの:あなたがちょうど重なって4つの以上の項目があるデカルト積を処理する必要が

SELECT a.id, b.id, c.id 
FROM atable a, 
atable b, 
atable c 
WHERE a.start_time<=b.start_time 
AND b.start_time<=c.start_time 
AND a.id<>b.id 
AND b.id<>c.id 
AND a.id<>c.id 
AND a.start_time<=b.end_time 
AND a.end_time>=b.start_time 
AND b.start_time>=c.end_time 
AND b.end_time>=c.start_time; 

関連する問題