Subtract two TDATETIME variables in Delphi and return the result in minutes

11.8k Views Asked by At

I have two TDateTime variables, like this:

s := StrToDateTime('03/03/2017 10:10:12');
e := StrToDateTime('04/04/2017 10:10:12');

I need to find out the difference between them, in hh:mm:ss format.

The ...Between() functions are not helping me here.

3

There are 3 best solutions below

5
LU RD On BEST ANSWER

Use the DateUtils.SecondsBetween function:

Uses
  DateUtils,SysUtils;

function TimeDiffStr(const s1,s2: String): String;
var
  t1,t2: TDateTime;
  secs: Int64;
begin
  t1 := StrToDateTime(s1); 
  t2 := StrToDateTime(s2); 
  secs := SecondsBetween(t1,t2);
  Result := Format('%2.2d:%2.2d:%2.2d',[secs div SecsPerHour,(secs div SecsPerMin) mod SecPerMin,secs mod SecsPerMin]);
end;

begin
  WriteLn(TimeDiffStr('03/03/2017 10:10:12','04/04/2017 10:10:12'));
  ReadLn;
end.

From the number of seconds, calculate the hours,minutes and remaining seconds.


If you want the difference in minutes, use the DateUtils.MinutesBetween function:

function TimeDiffStr(const s1,s2: String): String;
var
  t1,t2: TDateTime;
  minutes: Int64;
begin
  t1 := StrToDateTime(s1); 
  t2 := StrToDateTime(s2); 
  minutes := MinutesBetween(t1,t2);
  Result := Format('%2.2d:%2.2d:%2.2d',[minutes div MinsPerHour,minutes mod MinsPerHour,0]);
end;
4
Ken White On

You can use TTimeSpan (from the System.TimeSpan unit).

program Project1;

{$APPTYPE CONSOLE}

uses
  System.SysUtils, System.TimeSpan;

var
  StartDate, EndDate: TDateTime;
  TS: TTimeSpan;
  Temp: string;
begin
  StartDate := StrToDateTime('03/03/2017 10:10:12');
  EndDate := StrToDateTime('04/04/2017 10:10:12');
  TS := TTimeSpan.Subtract(EndDate, StartDate);
  Temp := TS;
  WriteLn(Temp);  // Outputs 32.00:00:00
  // The next line outputs the same as the one above
  WriteLn(Format('%.2d:%.2d:%.2d:%.2d', [TS.Days, TS.Hours, TS.Minutes, TS.Seconds]));
  WriteLn(TS.TotalMinutes); // Outputs 4.60800000000000E+0004
  WriteLn(Trunc(TS.TotalMinutes)); // Outputs 46080

  // This one will give the output you want (768:00:00)
  WriteLn(Format('%.2d:%.2d:%.2d', [TS.Days * 24 + TS.Hours, TS.Minutes, TS.Seconds]));
  ReadLn;
end.
3
Remy Lebeau On

First off, don't use hard-coded strings for date/time values. That is subject to localization issues, and it is just wasted overhead anyway. Use the SysUtils.EncodeDate() and SysUtils.EncodeTime() functions, or the DateUtils.EncodeDateTime() function.

Second, the ...Between() functions can indeed be usedneed, in particular SecondsBetween(). You can calculate the individual components from that return value.

Try something like this:

uses
  ..., SysUtils, DateUtils;

var
  s, e: TDateTime;
  diff: Int64;
  days, hours, mins, secs: Integer;
  s: string;
begin
  s := EncodeDateTime(2017, 3, 3, 10, 10, 12, 0);
  e := EncodeDateTime(2017, 4, 4, 10, 10, 12, 0);

  diff := SecondsBetween(e, s);

  days := diff div SecsPerDay;
  diff := diff mod SecsPerDay;

  hours := diff div SecsPerHour;
  diff := diff mod SecsPerHour;

  mins := diff div SecsPerMin;
  diff := diff mod SecsPerMin;

  secs := diff;

  s := Format('%d:%d:%d:%d', [days, hours, mins, secs]);
end;