2013-02-13 14 views

cevap

8

DayOfTheWeek (DateUtils biriminden) ve başlangıç ​​tarihinden bitiş tarihine kadar yinelenen bir sayaç kullanmanız gerekir. (Ayrıca muhtemelen de sayımı gelenler dışlamak için, bayramların bir tablo gerekir.) Diğer bir deyişle parametrelerin sırayla (endişesi vermeyerek bu biraz artırabilir

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; 

, Götürmezse 't) uç veya son başlamadan önce önce başlangıç ​​ise, fonksiyon çalışmaya devam eder matter:

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

Teşekkür ederim ... İş dönüş sürelerini önemli ölçüde etkilemeyeceklerinden tatile ihtiyacım yok ... ama hafta sonları sorun. Ben bir şans vereceğim. – Sardukar

+0

Neredeyse aynı işlevi kullandım .. harika çalışır. Çok fazla örnek olabilir, bu yüzden birkaç tane tatil ile ilgili bir sorun varsa, genel olarak etkilemezler. – Sardukar

+7

Bir döngü olmadan bunu yapmak güzel olurdu. –

12

her gün ve her giriş parametreleri sırasına bağlı değildir döngü olmadan.

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. Güzel! Döngülemeyen bir çözüme bakma şansım olmadı - şimdi kesinlikle buna ihtiyacım yok. :-) –

+4

Diğer ikisinden farklı sonuçlar elde ediyorum, eğer fonksiyonum varsa, eğer 'dt1: = Now' ve' dt2: = IncYear (Now, 3) 'yi test edersem. – kobik

+5

@kobik, teşekkürler. Doğru gün numaralandırma fonksiyonu elbette '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; 

rutin BusinessDaysSinceFixedDate sabit tarihten itibaren iş günü sayısını hesaplar. İlgili olmayan tarih 25 Aralık 1899 Pazartesi'dir. Sadece geçen hafta sayısını (X div 7) sayar ve bunu 5 ile çarpır. Güne göre düzeltmek için bir ofset ekler. haftanın. (X mod 7) negatif tarih için negatif bir değer döndürür Not, 30 Aralık önce, yani, bir tarih, 1899

sadece başlangıç ​​ve bitiş tarihi BusinessDaysSinceFixedDate aramalar ve diğer bir çıkarır rutin BusinessDaysBetweenDates.

+4

+1. 'Abs', 'BusinessDaysBetweenDates' sonucuna ekleyebilirsiniz (böylece Günlerin sonucu her zaman pozitif olacaktır). – kobik

İlgili konular