How to correctly get date and time passed between

2019-02-27 02:56发布

I am creating this function:

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;

To get a response like:

 There has been "2 years, 4 months, 1 day, 7 hours, 30 minutes and 22 seconds" between those dates

My doubt is if my logic is correct in the case of counting days passed and if I will have to make the same calculations with the time part.

But if you know any free coded that already does that, it will save me much time!

Thanks.

3条回答
小情绪 Triste *
2楼-- · 2019-02-27 03:08

First deal with years and months, after that 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;
查看更多
Summer. ? 凉城
3楼-- · 2019-02-27 03:17

I'd use the following logic:

Y := YearsBetween(FromDate, ToDate);
FromDate := IncYear(FromDate, Y);

M := MonthsBetween(FromDate, ToDate);
FromDate := IncMonth(FromDate, M);

and so on
查看更多
We Are One
4楼-- · 2019-02-27 03:21

Regarding the day and time part you can ease your life with TTimeSpan found in System.TimeSpan:

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;

This will not solve the year, month part, though.

查看更多
登录 后发表回答