Frage

Ich suche nach einem Algorithmus, der einen Arbeitstag Arbeitszeitlänge berechnen helfen. Es wäre einen Eingangsdatumsbereich hat und dann läßt Subtraktion teilweise oder vollständig von diesem Zeitpunkt Bereich Zeitbereich Scheiben schneidende und das Ergebnis würde die Anzahl der Minuten (oder den Bruchteil / Mehrfach von einem Tag) nach links in dem ursprünglichen Datum Bereich liegt, nach Abzug aus den verschiedenen nicht-Arbeitszeitscheiben.

Beispiel:

Eingabedatumsbereich: 2010.01.04 11.21 - 2010.01.05 03.00
Subtrahieren alle teilweise oder vollständig überschneidenden Scheiben wie folgt aus:
Entfernen Sie den ganzen Tag Sonntag
Nicht Sonntag Entfernen von 11.00 bis 00.00
Nicht Sonntag Entfernen Zeit nach 05.00
Nicht Sonntag Entfernen Zeit vor 08.00 Uhr
Nicht-Sonntage entfernen Zeit von 9.15 bis 09.30 Uhr
Ausgang: Anzahl der Minuten im Eingabedatumsbereich links

ich etwas nicht brauchen übermäßig allgemein. Ich konnte die Regeln codiert, den Code zu vereinfachen. Wenn jemand von Beispielcode oder einer Bibliothek / Funktion irgendwo weiß oder einige Pseudo-Code Ideen hat, würde ich etwas lieben, mit zu beginnen. Ich habe nichts gesehen in DateUtils, zum Beispiel. Selbst eine grundlegende Funktion, die die Anzahl der Minuten der Überlappung in zwei Datumsbereiche berechnet einen guten Start zu subtrahieren wäre.

War es hilfreich?

Lösung

Interessante Anforderungen ... Aber nicht so schwer, in einer "fest einprogrammiert" Art und Weise zu erreichen.

Genießen

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;

Andere Tipps

Sie einfach die Routinen in DateUtils verwenden und anderswo, die Regeln zu implementieren Sie sich selbst beschreiben.

Wenn Sie eine Idee wollen Sie erhalten begonnen, aus dem Stehgreif Ich würde vorschlagen, die Minuten in Ihrem Eingangsbereich Berechnung (nicht vergessen, dass ein TDateTime-Wert eine Gleitkomma ist, wo der Integralwert ist die Anzahl der Tage und der Bruchteil ist ein Teil von einem Tag) dann durch den Bereich und für jeden ganzen Zahl Schritt (Tag) abziehen, um die entsprechende Anzahl von Minuten für diesen Tag von den gesamten auf der Grundlage Ihre Regeln und die Start- / Endzeit der ersten / letzten Tage Erhöhen in der Bereich, wenn diese Tage im Bereich angetroffen werden (intervenierende Tage natürlich komplett Zeiträume von 24 Stunden sind).

Wirklich mehr detailliert „outline“ bietet eine ebenso könnte die komplette Routine für Sie implementieren, was ich tun könnte, wenn ich mehr Zeit gehabt, die leider ich nicht jetzt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top