我正在创建这个功能:
function LiteralTimePassed(FromDate: TDateTime; ToDate: TDateTime = 0): string;
const
Coma = ', ';
var
Dt, Mt: Integer; { se dos dias contarem mais que 30/31 então aumenta o mês }
P: TDateTime;
HC: Boolean; { indica se já há um token antes do novo token, para colocar vírgula }
Token: string; { a parte do timestamp verificada no loop }
Literal: string;
Y, M, D, H, N, S: Integer; { ano, mês, dia, hora, minuto(n), segundo }
Ys, Ms, Ds, Hs, Ns, Ss: Boolean; { valida se valores maiores que 1 para adicionar 's' }
begin
{ retorna quanto tempo se passou desde a data 1 até a data 2 em forma literal }
if ToDate = 0 then ToDate := Now;
HC := False;
Literal := '';
P := ToDate-FromDate ;
Dt := (DaysInMonth(FromDate)-DayOf(FromDate))+(DaysInMonth(ToDate)-DayOf(ToDate));
Mt := Dt div DaysInMonth(ToDate);
Ys := VarAssign(Y, YearsBetween(ToDate, FromDate)) > 1;
Ms := VarAssign(M, (MonthsBetween(ToDate, FromDate)-(Y*MonthsPerYear))-Mt) > 1;
Ds := VarAssign(D, Dt mod DaysInMonth(ToDate)) > 1;
// I did not make the hour, minute and second, yet...
end;
获得如下回复:
There has been "2 years, 4 months, 1 day, 7 hours, 30 minutes and 22 seconds" between those dates
我怀疑的是,如果我的逻辑在计算过去的日子里是正确的,并且我是否必须对时间部分进行相同的计算。
但是如果你知道任何已经做过的免费编码,它将为我节省很多时间!
感谢。
答案 0 :(得分:4)
首先处理TTimeSpan之后的数年和数月:
procedure TimePassed(dt1,dt2: TDateTime);
var
y1,m1,d1,h1,mi1,s1,ms,y2,m2,d2,h2,mi2,s2,y,mo,d:word;
ts:TTimeSpan;
begin
DecodeDateTime(dt1,y1,m1,d1,h1,mi1,s1,ms);
DecodeDateTime(dt2,y2,m2,d2,h2,mi2,s2,ms);
ms:=12*y2+m2-12*y1-m1;
if s1+60*mi1+60*60*h1+24*60*60*d1>s2+60*mi2+60*60*h2+24*60*60*d2 then ms:=ms-1;
mo:= ms mod 12;
y:=ms div 12; //years and months ready, now the rest
dt1:=EncodeDateTime(y1+y,m1+mo,d1,h1,mi1,s1,0);
ts := TTimeSpan.Subtract(dt2, dt1);
Result:= Format('There has been "%d years, %d months, %d days, %d hours, %d minutes and %d seconds" between those dates',
[y,mo,ts.Days, ts.Hours, ts.Minutes, ts.Seconds]);
end;
答案 1 :(得分:3)
关于日期和时间部分,您可以使用System.TimeSpan中找到的TTimeSpan来缓解您的生活:
var
ts: TTimeSpan;
begin
ts := TTimeSpan.Subtract(ToDate, FromDate);
Format('There has been "%d days, %d hours, %d minutes and %d seconds" between those dates',
[ts.Days, ts.Hours, ts.Minutes, ts.Seconds]);
end;
但这不会解决年,月的问题。
答案 2 :(得分:1)
我使用以下逻辑:
Y := YearsBetween(FromDate, ToDate);
FromDate := IncYear(FromDate, Y);
M := MonthsBetween(FromDate, ToDate);
FromDate := IncMonth(FromDate, M);
and so on