2

我正在寻找一种有助于计算工作日工作时间长度的算法。它将有一个输入日期范围,然后允许从该日期范围中减去部分或完全相交的时间范围切片,结果将是减去后原始日期范围中剩余的分钟数(或一天的分数/倍数)出各种非工作时间片。

例如:

输入日期范围:2010 年 1 月 4 日上午 11:21 - 2010 年 1 月 5 日下午 3:00
减去任何部分或完全相交的切片,如下所示:
删除全天 Sunday
Non-Sundays 删除 11:00 - 12:00
Non -周日下午 5:00 之后
的移除时间 非周日上午 8:00 之前的移除时间
非周日移除时间 9:15 - 9:30 am
输出:输入日期范围内剩余的分钟数

我不需要任何过于笼统的东西。我可以硬编码规则以简化代码。如果有人知道某个地方的示例代码或库/函数,或者有一些伪代码的想法,我会喜欢一些东西。例如,我在 DateUtils 中没有看到任何内容。即使是计算两个日期范围内重叠分钟数以减去的基本函数也是一个好的开始。

4

2 回答 2

4

有趣的要求......但以“硬编码”的方式实现并不难。

享受

uses
  Math, DateUtils;

function TimeRangeOverlap(Range1Start, Range1Finish, Range2Start, Range2Finish : TDateTime) : TDateTime;
begin
  Result := Max(Min(Range1Finish, Range2Finish) - Max(Range1Start, Range2Start), 0);
end;

function TotalTime(Start, Finish : TDateTime) : TDateTime;
var DayStart, DayFinish : TDateTime;
    I : Integer;
begin
  Result := 0;
  for I := Floor(Start) to Floor(Finish) do  //For each day in range;
  begin
    if DayOfWeek(I) = 1 then CONTINUE; //Remove all sundays.

    DayStart := Max(Start, I);     //Midnight on the start of the day, except on the first day;
    DayFinish   := Min(Finish, I + 1 - OneMillisecond); //Midnight minus 1 msec of the following day.

    Result := Result + DayFinish - DayStart;

    //Adjustment part
    Result := Result - TimeRangeOverlap(DayStart, DayFinish, I + EncodeTime(11,00,00,00), I + EncodeTime(12,00,00,00)); //Remove time between 11:00 and 12:00
    Result := Result - TimeRangeOverlap(DayStart, DayFinish, I + EncodeTime(17,00,00,00), I + 1); //Remove time after 5:00 PM
    Result := Result - TimeRangeOverlap(DayStart, DayFinish, I                          , I + EncodeTime(8,00,00,00)); //Remove time after 8:00 AM
    Result := Result - TimeRangeOverlap(DayStart, DayFinish, I + EncodeTime(9,15,00,00), I + EncodeTime(9,30,00,00)); //Remove time between 9:15 and 9:30
  end;
end;
于 2010-04-07T02:44:50.603 回答
1

只需使用 DateUtils 和其他地方的例程来实现您自己描述的规则。

如果您想要一个想法来帮助您入门,我建议您立即计算输入范围内的分钟数(请记住,TDateTime 值是一个浮点数,其中整数值是天数,小数部分是一部分一天)然后通过范围递增,并且对于每个整数步长(天),根据您的规则和范围内第一天/最后一天的开始/结束时间从总数中减去该天的适当分钟数那些日子是在范围内遇到的(中间的日子当然是完整的 24 小时周期)。

真的要提供任何更详细的“大纲”,还不如为您实现完整的例程,如果我有更多时间,我可能会这样做,遗憾的是我现在没有。

于 2010-04-06T23:26:16.950 回答