请教日期算法 ( 积分: 100 )

  • 主题发起人 主题发起人 johnkan
  • 开始时间 开始时间
J

johnkan

Unregistered / Unconfirmed
GUEST, unregistred user!
有一个简单的排班表,请教一下日期算法,
员工A,逢星期一、三、五上晚班,也是就是一个星期三个晚班,我们公司想安排A在第12个晚班时休息。求每12个晚班的准确日期!
如今天是员工A的第一个晚班2007年5月21日,第十二个晚班应该就是2007年6月15日。
先谢谢了
 
简单的很吗 restdate:=firstdate+25;
如果是要第n个休班 restdaten:=firstdate+25+(n-1)*28;
 
以上算法考虑不周全,感觉不太能完全解决问题,考虑中。。。
 
这个应该没有问题。。。。

===================
//初始化日期。
d:= now();
//计算日期d为开始时间的第12次上班日期
for i:= 0 to 10 do //加11次
case(DayOfWeek(d)) of
2,4:d:=d+2; //周一、周三加两日
6:d:=d+3; //周五加三日
else
begin
ShowMessage('日期错误:输入的日期非晚班时间,无法计算出休息日期!');
Exit;
end;
end;
Showmessage('下个休息日:'+ DateToStr(d));
 
请问25是怎样得出来的?能否详细点,如可以的话,能给详细点的算法说明,谢谢
 
你这个问题加25天是正确的,因为这12个晚班正好能被3整除,不存在半周的问题。。
 
请问qqjm如果我随便设定一星期的时间,如星期一,四,或二,五,六呢?case可能做不到这么活吧!还是先谢谢了
 
delphi帮助里输入DateUtils routines,有许多日期函数,
算法的问题,不难,自己去组装吧
 
TO: qqjm 为什么我将这段
for i:= 0 to 10 do //加11次
case(DayOfWeek(d)) of
2,4:d:=d+2; //周一、周三加两日
6:d:=d+3; //周五加三日
else
begin
ShowMessage('日期错误:输入的日期非晚班时间,无法计算出休息日期!');
Exit;
end;
改为

for i:= 0 to 6 do //加7次
case(DayOfWeek(d)) of
2:d:=d+1; //周一加一日
5:d:=d+2; //周四加二日
else
begin
ShowMessage('日期错误:输入的日期非晚班时间,无法计算出休息日期!');
Exit;
end;

就出错,请问有有什么不对的地方?
 
可不可说出一些日期函数
 
用这个代码可以动态设置上班的时间。如星期一,四,或二,五,六。


var
d:TdateTime;
i,lsLeng,lsIdx,i1:integer;
ls:array of integer;
begin

//初始化日期。
d:= now();
i1:= 12 ;//班次


//加载上班时间列表(必需是已经按从小到大排好序的),星期天为1,周6为7
setLength(ls,3);
ls[0]:=2;
ls[1]:=4;
ls[2]:=6;
lsLeng:= Length(ls);
for i:=0 to lsLeng do
begin
if i= lsLeng then
begin
ShowMessage('日期错误:输入的日期非晚班时间,无法计算出休息日期!');
exit;
end;
if DayOfWeek(d)= ls then
begin
lsIdx:= i;//记录位置
break;
end;
end;


lsIdx:= (lsIdx+lsLeng-1) mod lsLeng;



//25天的来由(7*(12/3)-3),因为5-21号是星期一,最后那个晚班,与下次的首个晚班有3天的间隔所以7*4周-3天=25天。
//但是如果是从周三开始计的话就不同了应该是+26!

if ls[lsIdx mod lsLeng] > ls[(lsIdx +1) mod lsLeng] then //因为周是循环的不是简单的周6-周4=2这么简单,所以写成这样,没办法。
d:= d+ 7*(i1 div lsLeng) - (7 + ls[(lsIdx+1) mod lsLeng ]-ls[lsIdx mod lsLeng] )
else
d:=d+ 7*(i1 div lsLeng) -( ls[(lsIdx+1) mod lsLeng]-ls[lsIdx mod lsLeng]);



//这里解决半周问题
if(i1 mod lsLeng)>0 then //如果存在半周的问题的,那只能一个一个把各班的时间间隔加上去。
begin

for i:=lsIdx to lsIdx + (i1 mod lsLeng)-1 do/
begin
if ls[i mod lsLeng] > ls[(i +1) mod lsLeng] then
d:= d+ (7 + ls[(i+1) mod lsLeng ]-ls[i mod lsLeng] )
else
d:=d+ ls[(i+1) mod lsLeng]-ls[i mod lsLeng];
end;

end;



Showmessage('下个休息日:'+ DateToStr(d));

end;
 
真的谢谢各位的帮忙,问题解决了,好完美的解决方法以!谢谢了!
 
To: qqjm
算法好像有问题,当一个星期为2天的时候,不能做到第8天休息,去到第9日,一个星期为三天时,会到第14天去。
为什么?
 
TO:qqjm
为什么我把程序改成这样就无法得到正确日期?

//初始化日期。
D := MonthCalendar1.Date; //D:=now() 时可以算出正确日期
i1:= StrToInt(Edit1.Text);//班次


//加载上班时间列表(必需是已经按从小到大排好序的),星期天为1,周6为7


{如果我出现5.26(星期六)为第一班,5.30(星期三),那排序就变成(7,4),不能从小到大排列了}

Setlength(ls,CellCount);
for P := 0 to CellCount-1 do
ls[P] := DayofWeek(StrtoDateTime(AdvStringGrid1.cells[1,P+1]));
 
对不起,自己解决了,太久没写的DELPHI,犯了低级错误,打扰了
 
后退
顶部