2012-10-29 24 views
5

私は複雑な作業をしているので、私は今数日間壁に頭を打っています。私は約4つのアプローチを試しましたが、それぞれがストールしているように見えて、非常にイライラしています。時間範囲を他の時間範囲で分割する

時間があります。たとえば、14:30〜18:30:00です。この時間範囲を誰かの仕事シフトと考えてください。この時間帯には、15:30から16:30まで、17:30から18:30までは働きません。競合するシフトを取り除くために、元のシフトの開始時刻と終了時刻を変更する必要があります。

オリジナルシフト配列は次のようになります。

$original_shift[0]['start'] = '14:30:00'; 
$original_shift[0]['end'] = '18:30:00'; 

と時間は次のようになり、元のシフトから削除する範囲:ここでは

$subshift[0]['start'] = '15:30:00'; 
$subshift[0]['end'] = '16:30:00'; 
$subshift[1]['start'] = '17:30:00'; 
$subshift[1]['end'] = '18:30:00'; 

は視覚化したものです:

enter image description here

私が行ってる時に次のようになります。

$original_shift[0]['start'] = '14:30:00'; 
$original_shift[0]['end'] = '15:30:00'; 
$original_shift[1]['start'] = '16:30:00'; 
$original_shift[1]['end'] = '17:30:00'; 

を私も考慮する必要があるいくつかの合併症は以下のとおりです。

  1. これらの時間範囲は、任意の時間(私が持っている半分の時間に制約されないかもしれ私の例では使用されています)、しかし、私は、利用不可能な時間範囲が常に最初のシフトの開始時間と終了時間の間に開始し、終了することを100%確信しています。

  2. 使用不可能な時間は、元のシフトの時間全体を突き合わせることができます。

私は過去にこのようなものを扱っている誰かを捜していると、彼らはそれを達成する方法にいくつかの洞察力を持っていることと同じくらいの「私のコードを書く」ために誰かを探していませんよ。

+0

私はいくつかの説明をしましたが、最後のコードブロックには方法が示されていません。 –

+0

は、元のシフトが既にセグメント化されていることができます。それはすでに使用できない時間を含んでいますか? – Gordon

答えて

3

あなたは具体的な答えとして、「いくらかの洞察力」を求めていたので、私は個人的には「分」を入力した配列を使っていました。

$shift = array(
    'start' => '15:30:00', 
    'end' => '18:30:00', 

    'original' => array(), 
    'unavailable' => array(), 
    'modified' => array() 
); 

あなたはその後、あなたの開始時刻と終了時刻の差を与える1110(分単位)に930と18:30:0015:30:00を変換するために、いくつかのjiggeryのpokeryにしてください。

使用range()迅速同様の形式でunavailableoriginal配列、負荷を埋めた後、使用できないオリジナルのシフトからその分動作するようにarray_intersect()array_diff()のようなものを使用します。

そこから、modifiedアレイを構築し、そこから直接出力を読み込みます。

+0

ありがとう!何らかの理由で、分単位で(整数として)作業することは決してありませんでした。私は実際には前のステップからの分単位の整数で時間を持っているので、これはもともとやっていたものとよく噛み合っています。私はあなたが提案したものを超えてもう少し作業をして解決策を思いつくことができましたが、あなたは私を正しい考え方に乗せるのを助けました。 –

1

コードが自身のために話す必要があります。

$original_shift[0]['start'] = '14:30:00'; 
$original_shift[0]['end'] = '18:30:00'; 

$breaks[0]['start'] = '14:30:00'; 
$breaks[0]['end'] = '15:30:00'; 
$breaks[1]['start'] = '16:30:00'; 
$breaks[1]['end'] = '17:30:00'; 

$modified_shift = array(
    array('start' => $original_shift[0]['start']) 
); 

for($x = 0, $y = count($breaks), $z = 0; $x < $y; $x++){ 
    $modified_shift[$z]['end'] = $breaks[$x]['start']; 
    if($modified_shift[$z]['end'] != $modified_shift[$z]['start']){ 
     $z++;  
    } 
    $modified_shift[$z]['start'] = $breaks[$x]['end']; 
} 

$modified_shift[$z]['end'] = $original_shift[0]['end']; 

if($modified_shift[$z]['end'] == $modified_shift[$z]['start']){ 
    unset($modified_shift[$z]); 
} 
2

あなたは、時間範囲の計算を行う必要があります。イメージが示すように、これは単純な減算のように思えます。これらを行うオブジェクトを持つだけでいいですね。

私はこの準備のためのコードを持っていなかったので、以下のコンセプトは多分悪くないかもしれませんが少し荒いです。

Rangeからの時間を表すタイプです。これらは既存のタイプの利点を利用できるようにDateTimeです。これまでのメリットの多くは使用しませんでしたが、アプリケーションの残りの部分ではこれが意味をなさすことができます。

タイプはすでに計算の一部を行うのに便利だと思ったいくつかの基本的な比較方法が既に含まれています。

しかし、オブジェクトは2つに分割できないため、Rangeを表すことができるRangesタイプも作成しました。これは「分ける」ことができるものを持つために必要でした。

Rangeのメンバーとして差分計算を実装しており、1つまたは複数のRangeオブジェクトを含む配列を返しているため、私はここで少しうんざりしました。最終的な計算は、その後だけシフトを有し、そこから利用できない範囲substractれる:

$shift = new Ranges(new DateTime('14:30:00'), new DateTime('18:30:00')); 

$unavailables = new Ranges([ 
    new Range(new DateTime('15:30:00'), new DateTime('16:30:00')), 
    new Range(new DateTime('17:30:00'), new DateTime('18:30:00')), 
]); 

$shift->subtract($unavailables); 

シフトは、次に及ぶ:

14:30:00 - 15:30:00 
16:30:00 - 17:30:00 

Demoと、 Gist

それは抽象化の価値がある場合、私が言うことはできませんが、どのようなDateTimeオブジェクトとの素敵なことは、あなたが><=とそれらを比較することができるということです。範囲と範囲の間でより多くの計算が必要な場合、これらのクラスの実際のメリットが明らかになります。たぶんインターフェイスはまだ甘いものではないかもしれませんが、基本的な計算はコードですでに概説されています。

注意点:14:00-15:0014:00-15:00の違いは14:00-14:00です。私は開始時間を空にしないでくださいが、あなたも空にすることができます。 Rangesオブジェクトはそれをうまく処理する必要があります。

+0

逆の操作のいくつかの欠陥がありました。私は要点を更新しました。更新されたデモはここにあります:http://codepad.viper-7.com/jy2Uz5 – hakre

+0

ありがとう、このコードは非常に有望です。私はおそらくそれを答えとして受け入れていただろう(私は可能な場合はDateTimeを好む)、しかし先駆け(そして私が省略した何か)はこれの前のステップで、私はまっすぐな時間(例えば8時に480時)からDateTimeオブジェクト。以下のJoeのソリューションは、時間の分のみのバージョンで直接作業することを提案しました。彼の解決策が働いて私に一歩を救います。それが私を答えとして選択する唯一の理由です。この回答にあなたが取り組んだ作業は大変ありがとうございます! –

+0

内部的にはこの配列も配列ですが、開始/終了の比較を行うことで数値の範囲(1分あたり1要素)を保つことができます。これは、分かりやすい開始値と終了値でも同様に機能し、一度(時間ベースではない)同様の必要性があるため、これらの範囲をより抽象化することについても考えました。それを書くのも面白かったし、素早くやっているし、メソッドの名前には完全に満足していない。しかし、たとえ配列を使って作業していても、範囲とメソッドをまとめてコードをリーンに保つために基本型を作成することをお勧めします。あなたのプロジェクトに幸運。 – hakre

関連する問題