5

私は複雑な仕事をしており、ここ数日間頭を壁にぶつけています。私は約4つの異なるアプローチを試しましたが、それぞれが失速しているようで、非常にイライラしています.

時間帯があります。たとえば、14:30:00 から 18:30:00 まで。この時間範囲の誰かの勤務シフトを考えてみましょう。この時間帯では、15:30:00 から 16:30:00 まで、および 17:30:00 から 18:30:00 までは勤務できないと述べています。競合するシフトを削除するために、元のシフトの開始時刻と終了時刻を変更する必要があります。

元のシフト配列は次のようになります。

$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';

これが視覚化です:

ここに画像の説明を入力

したがって、基本的には、完了したら元のシフトを次のようにする必要があります。

$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. これらの時間範囲はいつでもかまいません (私の例で使用したように 30 分に制限されていません)。終了時間。

  2. 利用できない時間により、元のシフトの時間が大幅に短縮されたり、時間がかかったりする可能性があります。

過去にこのようなことを扱ったことがあり、彼らがどのようにそれを達成したかについて何らかの洞察を持っている人を探しているのと同じくらい、「自分のコードを書く」人を探しているわけではありません。

4

3 に答える 3

3

時間範囲の計算を行う必要があります。画像が示すように、これは単純な減算のように見えます。これらを行うオブジェクトがあるだけでいいでしょう。

この準備ができたコードがなかったので、次の概念は少し大雑把ですが、おそらくそれほど悪くはありません。

Range時間 from ~ to を表す型。これらはDateTime、これらの既存のタイプの利点を使用できるようにするためのものです。これまでのところ、利点の多くを使用していませんでしたが、アプリケーションの残りの部分では、これは理にかなっています。

このRange型には、計算の一部を実行するのに役立つと思われるいくつかの基本的な比較メソッドが既に含まれています。

ただし、オブジェクトはそれ自体を 2 つに分割できないため、Ranges1 つまたは複数の を表現できる型も作成しましたRange。これは、「分割」できるものが必要でした。

Rangeのメンバとして差分計算を実装し、1 つまたは複数のRangeオブジェクトを含む配列を返すため、ここで少しごまかしました。最終的な計算は、シフトを行い、そこから利用できない範囲を差し引くだけです。

$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

デモ; 要旨

抽象化する価値があるかどうかはわかりませんが、オブジェクトの優れている点は、 、 、および とDateTime比較できることです。これらのクラスの真のメリットは、Range と Ranges の間でさらに計算が必要な場合に明らかになる可能性があります。インターフェイスはまだ甘いかもしれませんが、背後にある基本的な計算は既にコードで概説されています。><=

1 つの注意点:私のコードでの14:00-15:00との違いは、 になります。空走にならないように開始時間を守っていますが、空走も可能です。Ranges オブジェクトはそれを適切に処理する必要があります。14:00-15:0014:00-14:00

于 2012-10-30T00:57:50.970 に答える
3

完全に機能する回答ではなく、「ある程度の洞察」を具体的に求めたので、個人的には「分」が入力された配列を使用します。

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

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

15:30:00次に、930 と1110 (分数)に変換するためにジグリー ポーケリーを実行し18:30:00ます。これにより、開始時間と終了時間の差が得られます。

を使用range()して配列をすばやくいっぱいにし、同様の形式でoriginalロードしてから、 や などを使用して、元のシフトのどの分が利用できないかを調べます。unavailablearray_intersect()array_diff()

modifiedそこから配列を構築し、そこから直接出力を読み取ります。

于 2012-10-29T21:20:28.790 に答える
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]);
}
于 2012-10-29T21:34:56.100 に答える