Delphi 如何计算两个日期之间的工作日数?

Delphi 如何计算两个日期之间的工作日数?,delphi,delphi-xe2,Delphi,Delphi Xe2,我需要计算两个给定日期之间的工作日数。工作日是一周中除周六和周日以外的所有日子。我不把假期算在内 如何计算两个日期之间的工作日数?您需要使用(从DateUtils单元)和计数器,从开始日期到结束日期进行迭代。(您可能还需要一个假日表,以便将这些假日从您的计数中排除。) 函数BusinessDaysBetween(const StartDate,EndDate:TDateTime):整数; 变量 CurrDate:TDateTime; 开始 当前日期:=起始日期; 结果:=0; 而(CurrDat

我需要计算两个给定日期之间的工作日数。工作日是一周中除周六和周日以外的所有日子。我不把假期算在内

如何计算两个日期之间的工作日数?

您需要使用(从
DateUtils
单元)和计数器,从开始日期到结束日期进行迭代。(您可能还需要一个假日表,以便将这些假日从您的计数中排除。)

函数BusinessDaysBetween(const StartDate,EndDate:TDateTime):整数;
变量
CurrDate:TDateTime;
开始
当前日期:=起始日期;
结果:=0;

而(CurrDate不循环所有日期,输入参数不取决于顺序

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;
使用DateUtils、Math;
函数WorkingDaysBetween(const firstDate,secondDate:TDateTime):整数;
变量
startDate、stopDate:TDateTime;
startDow、stopDow:整数;
开始
如果(第一个日期<第二个日期),则
开始
起始日期:=第一个日期;
停止日期:=第二个日期;
结束
其他的
开始
起始日期:=第二个日期;
停止日期:=第一个日期;
结束;
startDow:=星期几(startDate);
stopDow:=星期几(停止日期);
如果(停止点>=开始点),则
stopDow:=最小值(stopDow,6)
其他的
公司(stopDow,5);
结果:=
5*周间隔(停止日期、开始日期)+
(stopDow-Min(startDow,6));
结束;
常规的BusinessDaysSinceFixedDate计算自固定日期起的工作日数。具体日期(不相关)为1899年12月25日星期一。 它只是计算过去的周数(xdiv7)并乘以5。 然后根据一周中的某一天添加一个偏移量进行校正。 请注意,(X mod 7)将返回负数日期的负值,即1899年12月30日之前的日期


日期之间的日常工作日只需调用BusinessDaysSinceFixedDate作为开始日期和结束日期,并从中减去一个。

我明白了,谢谢你……我不需要假期,因为它们不会显著影响周转时间。但是周末是个问题。我会尝试一下。我使用了几乎相同的功能。效果很好。有一个我们也可以这样做,所以如果很少有人对假期有异议,他们将不会影响整体。。谢谢。如果不进行循环,这将是很好的。@DavidHeffernan:+1。我的待办事项列表上有这个,只是为了好玩,但LU RD和user1008646击败了我。:)萨杜卡尔:你应该把你接受的答案改成@LURD或user1008648发布的答案。两者都比我的解决方案快得多。(user10008646的速度稍快,但IMO LURD的更易于阅读和以后维护。)+1。美好的我没有机会看到非循环解决方案-现在我肯定不需要这样做了。:-)如果我测试
dt1:=Now
dt2:=IncYear(Now,3)
@kobik,我会从其他两个函数中得到不同的结果,谢谢。正确的日期编号函数当然是
dayofweek()
+1。您可以将
Abs
添加到日期之间的
businessdaysbeween
的结果中(因此天数的结果将始终为正值)。
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;
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;
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;