Expired / time interval in Delphi?

I need to calculate the elapsed time (beautifully formatted) between now and the last change in the file date / time , i.e., something like this , only in my case the difference can be in days, months or even years.

I tried this:

var TimeDiff : Double; begin TimeDiff := Now - FileAgeEx('C:\my-file.txt'); if (TimeDiff >= 1) then Caption := FormatDateTime('dd hh:nn:ss', TimeDiff) else Caption := FormatDateTime('hh:nn:ss', TimeDiff); end; 

But (1) it does not work and (2) I would like to format it better.

Ultimately, my goal is to have something like this:

  • Diff time <1 day ==> show this: 12:00:01
  • Diff time> = 1 day ==> displays this: 25 days, 12:00:01
  • Diff time> = 1 year ==> it displays: 2 years, 3 months, 10 days, 12:00:01

Does anyone know how I can do this?

Thanks!

+4
source share
1 answer

The main problem, apparently, is getting the last modified file time. I am using the following code:

 function LastWriteTime(const FileName: string): TFileTime; var AttributeData: TWin32FileAttributeData; begin if not GetFileAttributesEx(PChar(FileName), GetFileExInfoStandard, @AttributeData) then RaiseLastOSError; Result := AttributeData.ftLastWriteTime; end; function UTCFileTimeToSystemTime(const FileTime: TFileTime): TSystemTime; //returns equivalent time in current locality, taking account of daylight saving var LocalFileTime: Windows.TFileTime; begin Windows.FileTimeToLocalFileTime(FileTime, LocalFileTime); Windows.FileTimeToSystemTime(LocalFileTime, Result); end; function UTCFileTimeToDateTime(const FileTime: TFileTime): TDateTime; begin Result := SystemTimeToDateTime(UTCFileTimeToSystemTime(FileTime)); end; 

You call LastWriteTime to get the last modified time in a time file format. Then call UTCFileTimeToDateTime to convert to TDateTime , taking into account the prevailing local machine time zone. Then you can compare this value with Now .

As for formatting, you already know how to do it. Your basic approach will work, and you just need to find out the details.


In the comments you say that

 FormatDateTime('dd hh:nn:ss', 2.9); 

shows a 1 for the day you expect a 2 . The problem is that this function formats dates, not time intervals. A value of 2.9 not considered elapsed time; rather, it is considered as an absolute date / time, 2.9 days after the Delphi era. I would use Trunc and Frac to get the number of days and part of the days respectively and work from there.

 Days := Trunc(TimeDiff); Time := Frac(TimeDiff); 

The following code, extracted directly from my code base, can give you a few pointers. Note that its input is in seconds, but it should set you on the right path.

 function CorrectPlural(const s: string; Count: Integer): string; begin Result := IntToStr(Count) + ' ' + s; if Count<>1 then begin Result := Result + 's'; end; end; function HumanReadableTime(Time: Double): string; //Time is in seconds const SecondsPerMinute = 60; SecondsPerHour = 60*SecondsPerMinute; SecondsPerDay = 24*SecondsPerHour; SecondsPerWeek = 7*SecondsPerDay; SecondsPerYear = 365*SecondsPerDay; var Years, Weeks, Days, Hours, Minutes, Seconds: Int64; begin Try Years := Trunc(Time/SecondsPerYear); Time := Time - Years*SecondsPerYear; Weeks := Trunc(Time/SecondsPerWeek); Time := Time - Weeks*SecondsPerWeek; Days := Trunc(Time/SecondsPerDay); Time := Time - Days*SecondsPerDay; Hours := Trunc(Time/SecondsPerHour); Time := Time - Hours*SecondsPerHour; Minutes := Trunc(Time/SecondsPerMinute); Time := Time - Minutes*SecondsPerMinute; Seconds := Trunc(Time); if Years>5000 then begin Result := IntToStr(Round(Years/1000))+' millennia'; end else if Years>500 then begin Result := IntToStr(Round(Years/100))+' centuries'; end else if Years>0 then begin Result := CorrectPlural('year', Years) + ' ' + CorrectPlural('week', Weeks); end else if Weeks>0 then begin Result := CorrectPlural('week', Weeks) + ' ' + CorrectPlural('day', Days); end else if Days>0 then begin Result := CorrectPlural('day', Days) + ' ' + CorrectPlural('hour', Hours); end else if Hours>0 then begin Result := CorrectPlural('hour', Hours) + ' ' + CorrectPlural('minute', Minutes); end else if Minutes>0 then begin Result := CorrectPlural('minute', Minutes); end else begin Result := CorrectPlural('second', Seconds); end; Except Result := 'an eternity'; End; end; 
+10
source

Source: https://habr.com/ru/post/1412156/


All Articles