2

就業時間の計算に役立つアルゴリズムを探しています。入力された日付範囲があり、その日付範囲から部分的または完全に交差する時間範囲スライスを減算できます。結果は、減算後に元の日付範囲に残っている分数(または1日の分数/倍数)になります。さまざまな非稼働タイムスライスを取り出します。

例えば:

入力日付範囲:1/4/2010 11:21 am-1/5/2010 3:00 pm次
のように部分的または完全に交差するスライスを減算します:
終日削除日曜日
非日曜日削除11:00-12:00
非-日曜日の午後5時以降の削除時間
非日曜日の午前8時前の削除時間
非日曜日の削除時間9 :15-9:30am
出力:入力された日付範囲の残り分数

過度に一般的なものは必要ありません。ルールをハードコーディングして、コードを単純化することができます。誰かがサンプルコードやライブラリ/関数をどこかで知っているか、疑似コードのアイデアを持っているなら、私は何かから始めたいと思います。たとえば、DateUtilsには何も表示されませんでした。2つの日付範囲のオーバーラップの分数を計算して減算する基本的な関数でさえ、良いスタートです。

4

2 に答える 2

4

興味深い要件...しかし、「ハードコードされた」方法で達成するのはそれほど難しくありません。

楽しみ

uses
  Math, DateUtils;

function TimeRangeOverlap(Range1Start, Range1Finish, Range2Start, Range2Finish : TDateTime) : TDateTime;
begin
  Result := Max(Min(Range1Finish, Range2Finish) - Max(Range1Start, Range2Start), 0);
end;

function TotalTime(Start, Finish : TDateTime) : TDateTime;
var DayStart, DayFinish : TDateTime;
    I : Integer;
begin
  Result := 0;
  for I := Floor(Start) to Floor(Finish) do  //For each day in range;
  begin
    if DayOfWeek(I) = 1 then CONTINUE; //Remove all sundays.

    DayStart := Max(Start, I);     //Midnight on the start of the day, except on the first day;
    DayFinish   := Min(Finish, I + 1 - OneMillisecond); //Midnight minus 1 msec of the following day.

    Result := Result + DayFinish - DayStart;

    //Adjustment part
    Result := Result - TimeRangeOverlap(DayStart, DayFinish, I + EncodeTime(11,00,00,00), I + EncodeTime(12,00,00,00)); //Remove time between 11:00 and 12:00
    Result := Result - TimeRangeOverlap(DayStart, DayFinish, I + EncodeTime(17,00,00,00), I + 1); //Remove time after 5:00 PM
    Result := Result - TimeRangeOverlap(DayStart, DayFinish, I                          , I + EncodeTime(8,00,00,00)); //Remove time after 8:00 AM
    Result := Result - TimeRangeOverlap(DayStart, DayFinish, I + EncodeTime(9,15,00,00), I + EncodeTime(9,30,00,00)); //Remove time between 9:15 and 9:30
  end;
end;
于 2010-04-07T02:44:50.603 に答える
1

DateUtilsやその他の場所でルーチンを使用するだけで、自分で説明したルールを実装できます。

開始するためのアイデアが必要な場合は、入力範囲の分を計算することをお勧めします(TDateTime値は浮動小数点であり、整数値は日数であり、小数部分は一部であることに注意してください)。次に、範囲をインクリメントし、整数ステップ(日)ごとに、ルールと範囲内の最初/最後の日の開始/終了時刻に基づいて、合計からその日の適切な分数を減算します。それらの日は範囲内で発生します(その間の日はもちろん24時間完了します)。

実際には、より詳細な「概要」を提供するために、完全なルーチンを実装することもできます。これは、時間があれば実行する可能性がありますが、残念ながら今は実行していません。

于 2010-04-06T23:26:16.950 に答える