我需要计算两个给定日期之间的工作日数(工作日)。工作日是一周中的所有日子,周六和周日除外。我不考虑把假期计入这个数量。
如何计算两个日期之间的工作日数?
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;
例程 BusinessDaysSinceFixedDate 计算自固定日期以来的工作日数。不相关的具体日期是 1899 年 12 月 25 日星期一。它只是计算已经过去的周数 (X div 7) 并将其乘以 5。然后它根据日期添加一个偏移量以进行更正星期。请注意, (X mod 7) 将为负日期返回负值,即 1899 年 12 月 30 日之前的日期。
例程 BusinessDaysBetweenDates 只需调用 BusinessDaysSinceFixedDate 来获取开始日期和结束日期,然后从另一个中减去一个。
无需循环所有天并且输入参数不取决于顺序。
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;
您需要使用DayOfTheWeek
(从DateUtils
单位)和一个计数器,从开始日期迭代到结束日期。(您可能还需要一张假期表,以将其排除在您的计数之外。)
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;
您可以通过不担心参数的顺序来稍微增强这一点(换句话说,无论 start 是在 end 之前还是 end 在 start 之前,该函数仍然可以工作):
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;