思路:
1. 计算整数天(每过 24 小时就有一个整数天)
2. 计算余数
3. 1 + 2 即为所求。
代码:
function HoursBetween(WorkhourStart, WorkhourEnd: TTime
StartAt, EndAt: TDateTime): Double;
// 指定时间的不足一天部分
function HoursOfTime(d: Double): Double;
begin
Result := d - Trunc(d);
end;
const
HOURS_OF_DAY = 24;
var
dHoursOfDay, dDaysInt, dDaysRemain: Double
// 每天工作时间,工作的整数天,不足一天的小时数
begin
// 确保 WorkHourStart, WorkHourEnd 及 StartAt, EndAt 大小顺序
// ...
/////////////////////////////////////////////////////////////
// 整数天小时数
dHoursOfDay := WorkHourEnd - WorkHourStart;
dDaysInt := Trunc(EndAt - StartAt);
StartAt := HoursOfTime(StartAt);
EndAt := HoursOfTime(EndAt);
/////////////////////////////////////////////////////////////
// 余数: 一天内
if StartAt < EndAt then
begin
if StartAt < WorkHourStart then // 提前上班,不算加班?
StartAt := WorkHourStart
else if StartAt > WorkHourEnd then // 下班后才上班, 白上
StartAt := WorkHourEnd;
if EndAt < WorkHourStart then // 上班前就下班,白上
EndAt := WorkHourStart
else if EndAt > WorkHourEnd then // 推迟下班,不算加班?
EndAt := WorkHourEnd;
dDaysRemain := EndAt - StartAt;
end
// 余数: 跨天
else if StartAt > EndAt then
begin
// 注:以下 StartAt 和 EndAt 作为了临时变量,分别保存前、后半天的工作时间
// 前半天
if StartAt < WorkHourStart then // 提前上班,一整天
StartAt := dHoursOfDay
else if StartAt < WorkHourEnd then // 迟到
StartAt := WorkHourEnd - StartAt
else if StartAt > WorkHourEnd then // 下班时间后上班,白上
StartAt := 0.0;
// 后半天
if EndAt < WorkHourStart then // 上班时间后下班,白上
EndAt := 0.0
else if EndAt < WorkHourEnd then // 早退
EndAt := EndAt - WorkHourStart
else if EndAt > WorkHourEnd then // 延后下班,一整天
EndAt := dHoursOfDay;
dDaysRemain := StartAt + EndAt;
end
// 余数: 重合
else
begin
dDaysRemain := 0.0;
end;
/////////////////////////////////////////////////////////////
// 结果
Result := (dHoursOfDay * dDaysInt + dDaysRemain) * HOURS_OF_DAY;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
WorkhourStart, WorkhourEnd: TTime;
StartAt, EndAt: TDateTime;
begin
WorkhourStart := StrToTime('9:00');
WorkhourEnd := StrToTime('17:00');
StartAt := StrToDateTime('2004-3-1 20:00');
EndAt := StrToDateTime('2004-3-3 5:00');
ShowMessage(Format('%f', [HoursBetween(WorkhourStart, WorkhourEnd, StartAt, EndAt)]));
end;
后记:
这是第三次贴的代码了,希望不会再错