如何计算两个TDateTime的相隔时间(年、月、日、时、分、秒)? (100分)

  • 主题发起人 叮叮当当
  • 开始时间

叮叮当当

Unregistered / Unconfirmed
GUEST, unregistred user!
要求编制一个过程返回两个TDateTime的经过时间(年、月、日、时、分、秒)
procedure DateTimeDiff(const T1, T2: TDateTime; out Y, M, D, H, N, S, MS: Word);
T2>T1,例如输入
T1=2002-5-29 20:30:10.100
T2=2002-5-29 20:31:11.000
返回 Y、M、D、H、N、S、MS
为: 0、0、0、0、1、0、900

VB里的TimeDiff函数是能完成类似功能的,Delphi的DateUtils里的函数我都查过了,没有适合的。[:(]
这个问题我想了几乎一个下午!如果用SecondsBetween函数得到经过的秒数再用整数除法计算分、时、日……会碰到闰年的问题。
 
var
ti,t2: TDateTime;
Year1, Month1, Day1, Hour1, Min1, Sec1, MSec1,
Year2, Month2, Day2, Hour2, Min2, Sec2, MSec2,
dYear, dMonth, dDay, dHour, dMin, dSec, dMSec: Word;
DecodeDate(t1, Year1, Month1, Day1);
DecodeTime(t1, Hour1, Min1, Sec1, MSec1);
DecodeDate(t2, Year2, Month2, Day2);
DecodeTime(t2, Hour2, Min2, Sec2, MSec2);
dYear:=Year1-Year2;
.......


 
t=T1-T2;
d=trunc(t);
t=t-d;
decodetime(t,h,n,s,ms);
decodedate(d,y,m,d)
decodedate(0,y0,m0,d0)
y,m,d与y0,m0,d0要减一下,这个不难吧

-------------------
http://www.8421.org
 
为什么老有人问这样的问题.
你只要明白一个事情:TDateTime=double
 
hi,你要知道这个就行了,
当初我想算两个Date之间有多少天,
后来发现两个Date相减就行了,
你有启发了么??
time也是一样啊。
 
procedure TimeDiff(FromDate,ToDate:TDateTime;Var DayGo:integer;var TimeGo:Ttime);
var
aTimeDiff:TDateTime;
begin
aTimeDiff:=ToDate-FromDate;
DayGo:=(trunc(aTimeDiff)); //逝去的日子
TimeGo:=aTimeDiff;//逝去的时间.
//注意没有日期部分的时间TIMEGO STRTODATE会成1887什么的,所以用TIMEGO要用TIMETOSTR
end;
 
随便给点分吧,好久没混分了,就是因为答了没人给分^_^
 
我要用做出来的DateTimeDiff过程显示“现在已经正常运行XX天XX月XX日XX小时XX分XX秒”,所以单纯地把年月日时分秒分离出来相减返回是不符合要求的。

我们先不管毫秒罢。
比如输入
T1=2002-5-31 20:59:59
T2=2002-6-01 19:00:00

会返回什么?
mlzhou的程序会返回“0年1月30天1小时59分59秒”,而正确的应该是“0年0月0天22小时0分1秒”

qdyoung的程序好像是正确的,我试试。
 
原来是这样,我的错了。
 
这个问题我问过
http://www.delphibbs.com/delphibbs/dispq.asp?lid=678320
 
qdyoung的程序也有问题,时间倒没有问题,日期用简单的相减就会有问题!

TO: xiao_ping
你的问题最后接受的是menxin的答案么?
 
二个相减,再用decode,唉~
 
TO: xiao_ping
menxin的程序最后好像也有问题(计算天数的地方):
r3:=DayOf(Date2)-DayOf(Date1) +IfThen(DayOf(Date1)<=DayOf(Date2),0,DaysInMonth(StartOfTheMonth(Date2)-1));
假如
Date1=2000-01-30
Date2=2000-03-31

StartOfTheMonth(Date2)=2000-03-01
StartOfTheMonth(Date2)-1=2000-02-29 (TDataTime的整数部分就是天数,减1就等于天数减1)
DaysInMonth(StartOfTheMonth(Date2)-1)=29
DayOf(Date1)<=DayOf(Date2) 成立,因此 r3:=DayOf(Date2)-DayOf(Date1) +29=31-30+29=30 (天)
这是错误的,应该是“2个月零1天”。
 

procedure timediff(FromDate, ToDate: TDateTime; var Y, M, D, H, N, S, MS: word);
var
d: TDateTime;
begin
d := ToDate-FromDate;
decodedate(d, y, m, d);
decodetime(d, h, n, s, ms);
end;
 
T1:=StrToDateTime('2002-5-29 20:30:10.100');
T2:=StrToDateTime('2002-5-29 20:31:11.000');
//为: 0、0、0、0、1、0、900
td:=t2-t1;
DecodeTime(td, Hour, Min, Sec, MSec);
DecodeDate(td, Year, Month, Day);
Label1.Caption:=IntToStr(floor(td))+'-'+IntToStr(hour)+'-'+IntToStr(min)+'-'+IntToStr(sec)+'-'+IntToStr(msec);
//为: 0-0-1-0-900
floor(td))为相差天数,如果超过30天月数加一,如果月数大于12年数加一进行折算。
 
明白TdateTime是Double就好了!
两个TDateTime相减,结果的整数部分就是天数
小数部分就是时分秒
例如,相减结果为3.256
则时间间隔为3天+0.256*24*60*60秒
再把这个秒数折算一下就是时分了!
 
TO: Pearl.
你想让我一上来就显示“已运行1899年12月30天……”啊?[:D]

TO: Oldtiger
我已经明白“TdateTime是Double”了。
也知道怎样计算经过的天数,可我不知道怎么把类似“768天”的计算结果转为显示“XX年XX月XX天”。[:(]要完成这个可没有想像的那么简单,因为可能要牵涉到闰年计算。
 
formatdatetime('yyyy-mm-dd hh:ss:nn:zzz',t1-t2);
 
只能确定可经过某年某月某日,但不能确定经过多少年多少月多少日,因为一年、有多
少日是不固定的。
 
顶部