BORLAND的答案我不满意:(1分)

  • 主题发起人 主题发起人 bottom
  • 开始时间 开始时间
B

bottom

Unregistered / Unconfirmed
GUEST, unregistred user!
BORLAND的答案我不满意:

根据两个日期求天数的算法

很麻烦,以下是个人看法,如有不对之处
或有更好的算法,欢迎修正并在论坛上贴
出你的观点,供大家讨论

BORLAND的答案我不满意:
Uses

DateUtils;
var
t1:TDateTime;
begin
t1:=DaysBetween(DateTimePicker1.Date,DateTimePicker2.Date);
edit2.Text:=datetostr(t1);
end;

程序运行结果:1900-3-8 这中结果你能满意吗?

所以决定自己研究


procedure TForm2.Button1Click(Sender: TObject);
var
i,j,k,jj,kk,m,n,
preyear,premonth,preday,
sucyear,sucmonth,sucday,
allday,
linshi1,linshi2,linshi3,
linshi4,linshi5,linshi6,
linshi7,linshi8,linshi9:longint;

s1,
s2:string;

_mm:array of longint;
_yy:array of longint;
begin
edit1.Text :=datetostr(DateTimePicker1.Date);
edit2.Text :=datetostr(DateTimePicker2.Date);
s1:=trim(edit1.Text );
s2:=trim(edit2.Text );
file://*********************处理大小,大的始终要坚持摆前面************
file://这样才方便程序编写不然容易造成思路混乱
fenjie1(s1,preyear,premonth,preday);
fenjie1(s2,sucyear,sucmonth,sucday);
if preyear<sucyear then
exchange(s1,s2);
if (preyear>=sucyear) and (premonth<sucmonth) then
exchange(s1,s2);
if (preyear>=sucyear) and (premonth>=sucmonth)and
(preday<sucday) then
exchange(s1,s2);
fenjie1(s1,preyear,premonth,preday);
fenjie1(s2,sucyear,sucmonth,sucday);


{按照人脑的思维习惯,采用“遍历”的思想来解决
比如:2001-12-15 到2003-7-22 :
2001-12-15到年末是16天,
中间经过了 2002一整年2002又是闰年366天,
2003-1-1 到2003-7-22号中间经过了,
31+28+31+30+31+30+22 总共:585天}


if (preyear=sucyear) and (premonth=sucmonth) then
file://最特殊的情况直接解决 ,不用遍历
begin//1
allday:=preday -sucday; file://2003-3-2 到 2003-3-28
exit;
end;//1
file://***************************************************************
m:=0;
n:=0;
linshi1:=0;
linshi2:=0;
linshi3:=0;
linshi4:=0;
linshi5:=0;
linshi6:=0;
linshi7:=0;
linshi8:=0;
linshi9:=0;
if (preyear=sucyear) and (premonth>sucmonth) then
file://年相等,开始遍历月
begin//1
j:=0;//月遍历开始
for i:=sucmonth to premonth do
begin//2
inc(j);
setlength(_mm,j);
_mm[j-1]:=i;//把月份保存在动态数组
end;//2


file://采用砍去头尾的做法
file://2003-7-22 减 2003-5-29天不够减要借月
{5-29 ~5-31 两天 6月份30天 7-1~7-22 22天
若要5月份到7月份完整算是31+30+31 所以砍去头尾多出来的部分就好
31-29 +30 +31-(31-22)}
file://2003-7-22 减 2003-5-21天够减不要借月
{5-21 ~5-31 10天 6月份30天 7-1~7-22 22天
若要5月份到7月份完整算是31+30+31 所以砍去头尾多出来的部分就好
31-21 +30 +31-(31-22)}


for i:=0 to high(_mm) do
begin//5
k:=_mm;
case k of
1,3,5,7,8,10,12:
begin//6
if (i=0) then
linshi1:=preday;
if (i=high(_mm)) then
linshi5:=31-sucday;
inc(m);
linshi2:=m*31;
end;//6
4,6,9,11:
begin//7
if (i=0) then
linshi1:=preday;
if (i=high(_mm)) then
linshi5:=30-sucday;
inc(n);
linshi3:=n*30;
end;//7
2:
begin//8
if isleap(preyear) then file://是闰年就有29天
linshi4:=29
else
linshi4:=28;
if (i=0) then
linshi1:=preday;
if (i=high(_mm)) then
linshi5:=linshi4-sucday;
end;//8
end;//end case
end;//5
allday:=linshi2+linshi3+linshi4-linshi5-linshi1;
exit;
end;//1


file://*****************************************************************
{2001-12-15 到2003-7-22}
m:=0;
n:=0;
linshi1:=0;
linshi2:=0;
linshi3:=0;
linshi4:=0;
linshi5:=0;
linshi6:=0;
linshi7:=0;
linshi8:=0;
linshi9:=0;
if (preyear>sucyear) then
begin//1
jj:=0;
for i:=sucyear to preyear do
begin//2
inc(jj);
setlength(_yy,jj);
_yy[jj-1]:=i; file://把年份保存在动态数组_yy中
end;//2
{同样还是利用砍去头尾的做法}
for i:=0 to high(_yy) do
begin//3
kk:=_yy;
if isleap(kk) then file://闰年
begin//4
inc(m);
linshi1:=kk*366;
end//4
else file://非闰年
begin//5
inc(n);
linshi2:=kk*365;
end;//5
end;//3
linshi3:=linshi1+linshi2;//年数加和
{2001-12-15 到2003-7-22}
file://要先减去2001-1-1 ~ 2001-12-14的天数
file://再减去2003-7-23 ~ 2003-12-31的天数
linshi4:=jianqian(preyear,premonth,preday);
linshi5:=jianhou(sucyear,sucmonth,sucday);
allday:=linshi3-linshi4-linshi5;
exit;
end;//1
end;


procedure fenjie1(const s:string;var yy,mm,dd:longint);
file://日期字符分解成年月日
var
s1,tmpstr:string;
i:longint;
begin
s1:=s;
i:=pos('-',s1);
tmpstr:=copy(s1,1,i-1);
yy:=strtoint(tmpstr);
s1:=copy(s1,i+1,length(s1));
i:=pos('-',s1);
tmpstr:=copy(s1,1,i-1);
mm:=strtoint(tmpstr);
s1:=copy(s1,i+1,length(s1));
dd:=strtoint(s1);
end;

procedure exchange(var s1,s2:string); // 字符串交换
var
tmpstr:string;
begin
tmpstr:=s1;
s1:=s2;
s2:=tmpstr;
end;

function isleap(yy:longint):boolean; file://判断润年
var
leap:longint;
begin
if yy mod 4=0 then leap:=0
else
if yy mod 100 <>0 then
leap:=1
else
if yy mod 400 <> 0 then
leap:=0
else
leap:=1;
if leap=1 then
Result:=true
else
Result:=false;
end;

function leapnumber(yy1,yy2:longint):longint; file://闰年个数
var
i:longint;
begin
Result:=0;
for i:=yy1 downto yy2 do
begin//1
if isleap(i) then
inc(Result);
end;//1
end;

function jianqian(yy,mm,dd:longint):longint; file://处理减去前面的时间
var
i,j,k,jj,kk,m,n,
linshi1,linshi2,linshi3,
linshi4,linshi5,linshi6,
linshi7,linshi8,linshi9:longint;
_mm:array of longint;
begin
Result:=0;
if isleap(yy) then
linshi1:=366
else
linshi1:=365;

m:=0;
n:=0;

j:=0;
for i:=1 to mm do file://注意这里
begin//2
inc(j);
setlength(_mm,j);
_mm[j-1]:=i; file://把月份保存在动态数组
end;//2
{2001-1-1 到2001-12-14}
for i:=0 to high(_mm) do
begin//5
k:=_mm;
case k of
1,3,5,7,8,10,12:
begin//6
if (i=high(_mm)) then
linshi5:=31-dd;
inc(m);
linshi2:=m*31;
end;//6
4,6,9,11:
begin//7
if (i=high(_mm)) then
linshi5:=30-dd;
inc(n);
linshi3:=n*30;
end;//7
2:
begin//8
if isleap(preyear) then file://是闰年就有29天
linshi4:=29
else
linshi4:=28;
if (i=high(_mm)) then
linshi5:=linshi4-dd;
end;//8
end;//end case
end;//5
linshi6:=linshi2+linshi3+linshi4-1-linshi5;
Result:=linshi1-linshi6;
end;


function jianhou(yy,mm,dd:longint):longint; file://处理减去后面的时间
var
i,j,k,jj,kk,m,n,
linshi1,linshi2,linshi3,
linshi4,linshi5,linshi6,
linshi7,linshi8,linshi9:longint;
_mm:array of longint;
begin
Result:=0;
if isleap(yy) then
linshi1:=366
else
linshi1:=365;

m:=0;
n:=0;

j:=0;
for i:=mm to 12 do file://注意这里
begin//2
inc(j);
setlength(_mm,j);
_mm[j-1]:=i; file://把月份保存在动态数组
end;//2
{2003-7-23 ~ 2003-12-31的天数}
for i:=0 to high(_mm) do
begin//5
k:=_mm;
case k of
1,3,5,7,8,10,12:
begin//6
if (i=0) then
linshi5:=dd;
inc(m);
linshi2:=m*31;
end;//6
4,6,9,11:
begin//7
if (i=0) then
linshi5:=dd;
inc(n);
linshi3:=n*30;
end;//7
2:
begin//8
if isleap(preyear) then file://是闰年就有29天
linshi4:=29
else
linshi4:=28;
if (i=0) then
linshi5:=dd;
end;//8
end;//end case
end;//5
allday:=linshi2+linshi3+linshi4-linshi5;
Result:=allday;
end;





 
程序写错了
Uses
DateUtils;
var
t1:integer;
begin
t1:=DaysBetween(DateTimePicker1.Date,DateTimePicker2.Date);
edit2.Text:=inttostr(t1);
end;
 
好麻烦。
CompareDate函数不行吗?
 
简单点,(DATE1-DATE2)+1即可.
 
太麻烦了,不过你能写出这么多代码也不容易了.DATE1-DATE2就可以了.
 
format('%5.2f',[data2-data1]);
 
[:D]钻研精神值得肯定
 
数值型的东西整这么复杂,呵呵
 
hehe,用错了,Borland的东西没错,自己写实在不值得
 
1900-1-1是初始日期
 
一句就搞定,跨年都没问题:
MessageBox(0,PChar(IntToStr(Trunc(StrToDate('2003-07-22')-StrToDate('2003-07-01')))),'相距',mb_ok);
 
这个东西帮助中已经写得很清楚了

TDatetime
所在单元:
     System
定义:
     type TDateTime = type Double;

整数部份表示日期
小数部分表示时间

其中整数部分的数字表示:
从1899年12月30日到某时间的天数,
如:
0 表示12/30/1899
-1 表示12/29/1899
注意:
只有在Delphi1中,日期是从公元1年开始计算,如果要从Delphi1中升级的话,
要把Delphi1中的时间减去693594.0

小数部份表示某天已过的时间
 
楼主应该去写底层~~~
 
十岁的小孩跟八岁的小孩差多少?
是差"两岁",不是差"一个两岁的小孩"!!!

楼主可能要说这个P4 CPU算出来的数据不对,于是拿了个烙铁要调整电路

(有时候开玩笑总是太尖刻,不好,要改正!)


 
不知道该说些什么了
 
开始看着我也晕了,后来看到大家的回答才醒过来~~~~~ [:D]
 
在下确实愚昧,但还是不理想啊!

t1:=StrToDate('2003-07-22');
t2:=StrToDate('2001-12-15');
t3:=Trunc(t1-t2);
s:=floatToStr(t3);
MessageBox(0,PChar(s),Pchar('相距'),mb_ok);

计算结果是 584

t1:=DaysBetween(DateTimePicker1.Date,DateTimePicker2.Date);
edit2.Text:=Inttostr(t1);

计算结果是583

以下是判断一个年是否是闰年的算法,对吗?

如果对2002是闰年吗?如果是我认为以上求出来是585天才对!

function isleap(yy:longint):boolean; file://判断润年
var
leap:longint;
begin
if yy mod 4=0 then leap:=0
else
if yy mod 100 <>0 then
leap:=1
else
if yy mod 400 <> 0 then
leap:=0
else
leap:=1;
if leap=1 then
Result:=true
else
Result:=false;
end;
 
请问各位前辈:如果给定两个日期,需要算出有效的上班天数(排除星期六日、五一、十一、春节等),是否有方便的方法;或者给定一个日期和天数,要求算出日期+天数后的某一天(排除星期六日、五一、十一、春节等),再此晚辈不胜感谢!
 
在下确实愚昧,但还是不理想啊!

t1:=StrToDate('2003-07-22');
t2:=StrToDate('2001-12-15');
t3:=Trunc(t1-t2);
s:=floatToStr(t3);
MessageBox(0,PChar(s),Pchar('相距'),mb_ok);

计算结果是 584

t1:=DaysBetween(DateTimePicker1.Date,DateTimePicker2.Date);
edit2.Text:=Inttostr(t1);

计算结果是583

以下是判断一个年是否是闰年的算法,对吗?

如果对2002是闰年吗?如果是我认为以上求出来是585天才对!

function isleap(yy:longint):boolean; file://判断润年
var
leap:longint;
begin
if yy mod 4=0 then leap:=0
else
if yy mod 100 <>0 then
leap:=1
else
if yy mod 400 <> 0 then
leap:=0
else
leap:=1;
if leap=1 then
Result:=true
else
Result:=false;
end;
 
不错,按你这么说就不能直接求了必须按我遍历的做法
 
后退
顶部