如何正确获取两个日期之间经过的日期和时间?

Ple*_*rds 2 delphi datetime delphi-xe6

我正在创建这个函数:

\n\n
function LiteralTimePassed(FromDate: TDateTime; ToDate: TDateTime = 0): string;\nconst\n  Coma = \', \';\nvar\n  Dt, Mt: Integer; { se dos dias contarem mais que 30/31 ent\xc3\xa3o aumenta o m\xc3\xaas }\n  P: TDateTime;\n  HC: Boolean; { indica se j\xc3\xa1 h\xc3\xa1 um token antes do novo token, para colocar v\xc3\xadrgula }\n  Token: string; { a parte do timestamp verificada no loop }\n  Literal: string;\n  Y, M, D, H, N, S: Integer; { ano, m\xc3\xaas, dia, hora, minuto(n), segundo }\n  Ys, Ms, Ds, Hs, Ns, Ss: Boolean; { valida se valores maiores que 1 para adicionar \'s\' }\nbegin\n{ retorna quanto tempo se passou desde a data 1 at\xc3\xa9 a data 2 em forma literal }\n  if ToDate = 0 then ToDate := Now;\n  HC := False;\n  Literal := \'\';\n  P := ToDate-FromDate ;\n   Dt := (DaysInMonth(FromDate)-DayOf(FromDate))+(DaysInMonth(ToDate)-DayOf(ToDate));\n   Mt := Dt div DaysInMonth(ToDate);\n  Ys := VarAssign(Y, YearsBetween(ToDate, FromDate)) > 1;\n  Ms := VarAssign(M, (MonthsBetween(ToDate, FromDate)-(Y*MonthsPerYear))-Mt) > 1;\n  Ds := VarAssign(D, Dt mod DaysInMonth(ToDate)) > 1;\n  // I did not make the hour, minute and second, yet...\nend;\n
Run Code Online (Sandbox Code Playgroud)\n\n

要获得如下响应:

\n\n
 There has been "2 years, 4 months, 1 day, 7 hours, 30 minutes and 22 seconds" between those dates\n
Run Code Online (Sandbox Code Playgroud)\n\n

我怀疑在计算过去的天数的情况下我的逻辑是否正确,以及我是否必须对时间部分进行相同的计算。

\n\n

但如果你知道任何已经做到这一点的免费编码,它将节省我很多时间!

\n\n

谢谢。

\n

LHr*_*tov 5

首先处理年和月,然后处理 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;
Run Code Online (Sandbox Code Playgroud)