Recent

Author Topic: [SOLVED] Format elapsed time to "X days, X hours, XX mins, XX secs"  (Read 3625 times)

Gizmo

  • Hero Member
  • *****
  • Posts: 831
This directly relates to this original thread from 2014 (http://forum.lazarus.freepascal.org/index.php?topic=25000.0), but, I did get an answer to that original question, thus, a new thread.

I want to display the time that has elapsed between start date and time and end date and time as "X days, X hours, H mins, and x seconds". It works fine for an elapsed time up to 24 hours, but after that it seems to reset. So if something takes three days and finishes at 08:30 in the morning, the elapsed time is rendered as "8 hrs, 30 min, 20 sec" instead of "3 days, 8 hrs, 30 min, 20 sec"

Code: [Select]
var
StartTime, EndTime, TimeDifference : TDateTime;
strTimeDifference : string;
begin
  // Compute the end time and how long it took.
  Startime := Now;
  lblStartTime.Caption := FormatDateTime('DD/MM/YY HH:MM:SS', StartTime);
  // some time later...
  EndTime := Now;
  lblEndTime.Caption := FormatDateTime('DD/MM/YY HH:MM:SS', EndTime);
  TimeDifference := EndTime - StartTime;
  strTimeDifference := FormatDateTime('h" hrs, "n" min, "s" sec"', TimeDifference);
  lblTimeTaken.Caption := strTimeDifference;
end;

So to achieve "3 days, 8 hrs, 30 min, 20 sec", which I accept the original idea does not extend to, I tried an adjustment :

Code: [Select]
  strTimeDifference := FormatDateTime('d" days, "h" hrs, "n" min, "s" sec"', TimeDifference);

but now, if something takes 10 seconds, I get the following output:

"30 days, 0 hrs, 0 min, 10 sec"

so I have no idea where the 30 days is coming from. I'm obviously not getting TDateTime properly but I assumed that if EndTime was 48 hours after StartTime, then strTimeDifference would would equal 48 hours. So when formatted with FormateDateTime, I assumed would become "2" (2 x 24 hours).

Where am I going wrong? 
« Last Edit: November 24, 2017, 03:28:03 pm by Gizmo »

wp

  • Hero Member
  • *****
  • Posts: 11923
Re: Format elapsed time to "X days, X hours, XX mins, XX secs"
« Reply #1 on: November 24, 2017, 02:10:15 pm »
The standard formatting rule assumes that time is the fractional part of a floating point value and thus cannot be greater than 1, i.e. hours are always < 24. But if you add the symbol "d" it will be replaced by the calendar day (usually in year 1900), not by the count of days. But of course you can combine the integer part of the time difference (= full days elapsed) with the FormatDateTime of the fraction part (hours, minutes, seconds):

Code: Pascal  [Select][+][-]
  1.   WriteLn(Format('%d days %s', [trunc(timediff), FormatDateTime('h" hrs "n" min "s" sec"', timediff)]));

There has been an Excel-like extension to FormatDateTime to allow for time differences. Hours >= 24, minutes >= 60 or seconds >= 60 can be displayed if the corresponding symbol is put into square brackets and if the option [fdoInterval] is used as last parameter in FormatDateTime. Unfortunately this new syntax does not take days into account.

Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   SysUtils;
  7.  
  8. var
  9.   timediff: TDateTime;
  10. begin
  11.   timediff := 3.2512345;
  12.   WriteLn(FormatDateTime('[h]" hr "n" min "s" sec"', timediff, [fdoInterval]));
  13.   WriteLn(FormatDateTime('[n]" min "s" sec"', timediff, [fdoInterval]));
  14.   WriteLn(FormatDateTime('[s]" seconds"', timediff, [fdoInterval]));
  15.  
  16.   ReadLn;
  17. end.

The "30" is displayed because the symbol "d" is replaced by the calendar day. The TDateTime values begin on Dec 30, 1899. If your time difference is 10 seconds, then the datetime variable has the value 10/(24*60*60), i.e. 0....(something). The calendar day of this value is 30 (its month would be 12, and its year 1899).
« Last Edit: November 24, 2017, 02:14:20 pm by wp »

Gizmo

  • Hero Member
  • *****
  • Posts: 831
Re: Format elapsed time to "X days, X hours, XX mins, XX secs"
« Reply #2 on: November 24, 2017, 03:27:54 pm »
Bless you WP! You've saved me again!

Thanks for the explanation and syntax help. I've done a quick test and that seems to work. I'll look more closely at home tonight.

Thanks

 

TinyPortal © 2005-2018