2013-02-13 47 views
11

Devo calcolare il conteggio dei giorni lavorativi (giorni lavorativi) tra due date date. I giorni lavorativi sono tutti i giorni della settimana tranne il sabato e la domenica. Non sto considerando le vacanze in questo conteggio.Come calcolare il conteggio dei giorni lavorativi tra due date?

Come calcolare il conteggio dei giorni lavorativi tra due date?

risposta

8

È necessario utilizzare DayOfTheWeek (dall'unità DateUtils) e un contatore, passando dalla data di inizio alla data di fine. (Avrete probabilmente anche bisogno di un tavolo di vacanze, per escludere quelli il valore anche.)

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; 

È possibile migliorare questo un po 'da non preoccuparsi l'ordine dei parametri (in altre parole, esso doesn 't importa se inizio è prima estremità o estremità è prima dell'avvio, la funzione continuerà a funzionare):

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

Vedo grazie ... Non ho bisogno di vacanze perché non influenzano in modo significativo i tempi di consegna..ma i fine settimana sono un problema. Darò un colpo. – Sardukar

+0

Ho usato quasi la stessa funzione ... funziona alla grande. ci sono anche gli esemplari, quindi se pochi hanno problemi con le vacanze non incideranno sul generale ... grazie. – Sardukar

+7

Sarebbe bello farlo senza un ciclo. –

12

senza annodare tutti i giorni e parametri di input non a seconda dell'ordine.

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. Bello! Non ho avuto la possibilità di guardare una soluzione senza loop - ora non ho assolutamente bisogno di farlo. :-) –

+4

Ottengo risultati diversi dagli altri due, con la tua funzione, se provo 'dt1: = Now' e' dt2: = IncYear (Now, 3) '. – kobik

+5

@kobik, grazie. La corretta funzione di numerazione del giorno è ovviamente '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; 

Il BusinessDaysSinceFixedDate di routine calcola il numero di giorni lavorativi dal momento che una data fissa. La data specifica, che è irrilevante, è lunedì 25 dicembre 1899. Conta semplicemente il numero di settimane trascorse (X div 7) e lo moltiplica per 5. Quindi aggiunge un offset per correggere in base al giorno della settimana. noti che (X mod 7) restituirà un valore negativo per una data negativa, cioè una data prima del 30 dicembre 1899.

I BusinessDaysBetweenDates di routine chiama semplicemente BusinessDaysSinceFixedDate per la data di inizio e di fine e sottrae uno dall'altro.

+4

+1. È possibile aggiungere 'Abs' al risultato di' BusinessDaysBetweenDates' (quindi il risultato di Days sarà sempre positivo). – kobik

Problemi correlati