2013-02-13 20 views

Antwort

8

Sie müssen DayOfTheWeek (von der DateUtils Einheit) und einen Zähler verwenden, der vom Startdatum bis zum Enddatum durchläuft. (Sie brauchen auch wahrscheinlich eine Tabelle der Ferien, auch solche, die aus Ihrer Zählung auszuschließen.)

function BusinessDaysBetween(const StartDate, EndDate: TDateTime): Integer; 
var 
    CurrDate : TDateTime; 
begin 
    CurrDate := StartDate; 
    Result := 0; 
    while (CurrDate <= EndDate) do 
    begin 
    // DayOfTheWeek returns 1-5 for Mon-Fri, so 6 and 7 are weekends 
    if DayOfTheWeek(CurrDate) < 6 then 
     Inc(Result); 
    CurrDate := CurrDate + 1; 
    end; 
end; 

Sie diese ein wenig verbessern können nicht über die Reihenfolge der Parameter sich Gedanken (in anderen Worten, es doesn ‚t gleich, ob Start ist vor dem Ende oder Ende vor dem Start ist, wird die Funktion immer noch funktionieren):

function BusinessDaysBetween(const FirstDate, SecondDate: TDateTime): Integer; 
var 
    CurrDate : TDateTime; 
    StartDate, EndDate: TDateTime; 
begin 
    if SecondDate > FirstDate then 
    begin 
    StartDate := FirstDate; 
    EndDate := SecondDate; 
    end 
    else 
    begin 
    StartDate := SecondDate; 
    EndDate := FirstDate; 
    end; 

    CurrDate := StartDate; 
    Result := 0; 

    while (CurrDate <= EndDate) do 
    begin 
    if DayOfTheWeek(CurrDate) < 6 then 
     Inc(Result); 
    CurrDate := CurrDate + 1; 
    end; 
end; 
+0

Ich sehe danke ... Ich brauche keine Ferien, da sie die Turnaround-Zeiten nicht signifikant beeinflussen werden..aber Wochenenden sind ein Problem. Ich werde es versuchen. – Sardukar

+0

Ich habe fast die gleiche Funktion verwendet .. funktioniert großartig. Es gibt viel zu viele Proben, wenn sie nur wenige Probleme mit den Ferien haben, werden sie nicht die gesamte ... thank you. – Sardukar

+7

Es wäre schön, dies ohne eine Schleife zu tun. –

12

ohne Looping all Tage und Eingabeparameter in Abhängigkeit nicht auf Bestellung.

Uses DateUtils,Math; 

function WorkingDaysBetween(const firstDate,secondDate : TDateTime) : Integer; 
var 
    startDate,stopDate : TDateTime; 
    startDow,stopDow : Integer; 
begin 
    if (firstDate < secondDate) then 
    begin 
    startDate := firstDate; 
    stopDate := secondDate; 
    end 
    else 
    begin 
    startDate := secondDate; 
    stopDate := firstDate; 
    end; 
    startDow := DayOfTheWeek(startDate); 
    stopDow := DayOfTheWeek(stopDate); 
    if (stopDow >= startDow) then 
    stopDow := Min(stopDow,6) 
    else 
    Inc(stopDow,5); 

    Result := 
    5*WeeksBetween(stopDate,startDate) + 
    (stopDow - Min(startDow,6)); 
end; 
+3

+1. Nett! Ich hatte keine Chance, eine Lösung ohne Schleife zu betrachten - jetzt muss ich das definitiv nicht tun. :-) –

+4

Ich bekomme andere Ergebnisse von den anderen beiden mit deiner Funktion, wenn ich 'dt1: = Jetzt 'und' dt2: = IncYear (Jetzt, 3) 'teste. – kobik

+5

@kobik, danke. Die korrekte Tagnummerierung ist natürlich 'DayOfTheWeek()'. –

13
function BusinessDaysSinceFixedDate (const nDate : tDateTime) : integer; 
const 
    Map : array [ -6 .. 6 ] of integer 
     = ( 0, 0, 1, 2, 3, 4, 5, 5, 5, 6, 7, 8, 9); 
var 
    X : integer; 
begin 
    X := trunc (nDate); 
    Result := 5 * (X div 7) + Map [ X mod 7 ]; 
end; 

function BusinessDaysBetweenDates (const nStartDate : tDateTime; 
            const nEndDate : tDateTime) : integer; 
begin 
    Result := BusinessDaysSinceFixedDate (nEndDate) 
      - BusinessDaysSinceFixedDate (nStartDate); 
end; 

Die Routine BusinessDaysSinceFixedDate berechnet die Anzahl der Arbeitstage seit einem bestimmten Datum. Das bestimmte Datum, das irrelevant ist, ist Montag, 25. Dezember 1899. Es zählt einfach die Anzahl der Wochen, die vergangen sind (X div 7) und multipliziert diese mit 5. Dann fügt es einen Offset hinzu, um basierend auf dem Tag zu korrigieren der Woche. beachten, daß (X mod 7) einen negativen Wert für ein negatives Datum zurück, das heißt ein Zeitpunkt vor dem 30. Dezember, 1899.

Die Routine BusinessDaysBetweenDates einfach BusinessDaysSinceFixedDate für das Start- und Enddatum aufruft und subtrahiert eine von dem anderen.

+4

+1. Sie könnten 'Abs' zum Ergebnis von 'BusinessDaysBetweenDates' hinzufügen (so dass das Ergebnis von Tagen immer positiv ist). – kobik

Verwandte Themen