In delphi application, sometime you need a timer to calculate the time or do something intervally.

there are some methods to get time or use a timer in delphi.

Timing  In Your Code

In some applications, very accurate, high-precision time measurement methods are important.

Using RTL’s Now Function

One option uses the  now() function.

Now, defined in the SysUtils unit, returns the current system date and time.

A few lines of code measure elapsed time between the “start” and “stop” of some process:

var
start, stop, elapsed : TDateTime;​
begin
start := Now;
//dosomething();
stop := Now;
elapsed := stop – start;
end;

The Now function returns the current system date and time that is accurate up to 15 milliseconds (Windows NT and later) or 55 milliseconds (Windows 98).

for normal works, this accuracy is enough.

For very small intervals the precision of “Now” is sometimes not enough.

Using Windows API GetTickCount

For even more precise time , use the GetTickCount Windows API function.

GetTickCount retrieves the number of milliseconds that have elapsed since the system was started, but the function only has the scale of 1 ms and may not  accurate if the computer remains powered-up for long periods of time.

The elapsed time is stored as a Cardinal (32-bit) value. Therefore, the time will wrap around to zero if Windows is run continuously for 49.7 days.

var
start, stop, elapsed : cardinal;
begin
start := GetTickCount;
//dosomething();
stop := GetTickCount;
elapsed := stop – start; //milliseconds
end;

GetTickCount is also limited to the accuracy of the system timer (10 / 55 ms), as the now() functions.

High Precision Timing

If your PC supports a high-resolution performance counter, use theQueryPerformanceFrequency Windows API function to express the frequency, in counts per second. The value of the count is processor dependent.

The QueryPerformanceCounter function retrieves the current value of the high-resolution performance counter. By calling this function at the beginning and end of a section of code, an application uses the counter as a high-resolution timer.

The accuracy of a high-resolution timers is around few hundred nanoseconds. A nanosecond is a unit of time representing 0.000000001 seconds — or 1 billionth of a second.

TStopWatch: Delphi Implementation Of a High Resolution Counter

New option, With a nod to .Net naming conventions, a counter like TStopWatch offers a high-resolution Delphi solution for precise time measurements.

TStopWatch measures elapsed time by counting timer ticks in the underlying timer mechanism.

  • The IsHighResolution property indicates whether the timer is based on a high-resolution performance counter.
  • The Start method starts measuring elapsed time.
  • The Stop method stops measuring elapsed time.
  • The ElapsedMilliseconds property gets the total elapsed time in milliseconds.
  • The Elapsed property gets the total elapsed time in timer ticks.

unit StopWatch;
interface
uses Windows, SysUtils, DateUtils;
type TStopWatch = class
private
fFrequency : TLargeInteger;
fIsRunning: boolean;
fIsHighResolution: boolean;
fStartCount, fStopCount : TLargeInteger;
procedure SetTickStamp(var lInt : TLargeInteger) ;
function GetElapsedTicks: TLargeInteger;
function GetElapsedMilliseconds: TLargeInteger;
function GetElapsed: string;
public
constructor Create(const startOnCreate : boolean = false) ;
procedure Start;
procedure Stop;
property IsHighResolution : boolean read fIsHighResolution;
property ElapsedTicks : TLargeInteger read GetElapsedTicks;
property ElapsedMilliseconds : TLargeInteger read GetElapsedMilliseconds;
property Elapsed : string read GetElapsed;
property IsRunning : boolean read fIsRunning;
end;
implementation
constructor TStopWatch.Create(const startOnCreate : boolean = false) ;
begin
inherited Create;
fIsRunning := false;
fIsHighResolution := QueryPerformanceFrequency(fFrequency) ;
if NOT fIsHighResolution then fFrequency := MSecsPerSec;
if startOnCreate then Start;
end;
function TStopWatch.GetElapsedTicks: TLargeInteger;
begin
result := fStopCount – fStartCount;
end;
procedure TStopWatch.SetTickStamp(var lInt : TLargeInteger) ;
begin
if fIsHighResolution then
QueryPerformanceCounter(lInt)
else
lInt := MilliSecondOf(Now) ;
end;
function TStopWatch.GetElapsed: string;
var
dt : TDateTime;
begin
dt := ElapsedMilliseconds / MSecsPerSec / SecsPerDay;
result := Format(‘%d days, %s’, [trunc(dt), FormatDateTime(‘hh:nn:ss.z’, Frac(dt))]) ;
end;
function TStopWatch.GetElapsedMilliseconds: TLargeInteger;
begin
result := (MSecsPerSec * (fStopCount – fStartCount)) div fFrequency;
end;
procedure TStopWatch.Start;
begin
SetTickStamp(fStartCount) ;
fIsRunning := true;
end;
procedure TStopWatch.Stop;
begin
SetTickStamp(fStopCount) ;
fIsRunning := false;
end;
end.

Here’s an example of usage:

var
sw : TStopWatch;
elapsedMilliseconds : cardinal;
begin
sw := TStopWatch.Create() ;
try
sw.Start;
//TimeOutThisFunction()
sw.Stop;
elapsedMilliseconds := sw.ElapsedMilliseconds;
finally
sw.Free;
end;
end;