Santiago López
Santiago López

Reputation: 21

Comparing datetimes in delphi

I am developing a quizing game in Delphi and I would like to have a timer so that players don´t have unlimited time to answer the questions. I am using the function "Time" to get the current time but I don´t know how to convert it to something like an integer so that when let´s say 10 seconds have passed the player loses it´s chance. It would look like something like this:

Var
CurrentTime,Aux:TDateTime;

Begin
CurrentTime:=Time; //Current Time is assigned to a global variable.
Aux:=CurrentTime;
While (Aux-10000<=CurrentTime) do
  Begin
     if (Answer:=True) then //If the answer is already given by the player we break the while loop
       Break;
     Aux:=Time; //We refresh the auxilary variable
     if (Aux-10000>=CurrentTime) then  //We check if 10 seconds have passed
       Begin
         showmessage('You have taken too much time, your turn is lost');
         exit; //We leave the script
       end;
  end;
end;
  

The problem is I can´t do arithmetic operations in DateTimes, as far as I know, So I need a different method for comparing the 2 different time instances. Any help would be appreciated, thanks!

Upvotes: 2

Views: 2184

Answers (2)

No&#39;am Newman
No&#39;am Newman

Reputation: 6477

I have written a few applications like this, using a TTimer. The timer's interval is set to 1000, which is equivalent to 1 second (you can use a different value); every time the timer's OnTimer event executes, a global variable is incremented which is then checked against the time limit (10 seconds?); if the variable equals this limit then first the timer is stopped, then the code performs whatever is necessary to transfer to the next person, or next question.

There should be similar code that executes when the person enters an answer as this code too needs to first save the answer then transfers to the next person. This portion should also stop the timer.

The 'show next question' part should restart the timer and reset the global variable only after the next question has been displayed, as it might take some time for it to be fetched.

Upvotes: 1

Remy Lebeau
Remy Lebeau

Reputation: 597941

TDate, TTime, and TDateTime are implemented using floating-point numbers, so you can perform arithmetic operations on them.

But you really shouldn't, in this case. The DateUtils unit has many functions for working with date/time values, eg:

uses
  ..., DateUtils;

var
  StartTime, Aux: TDateTime;
begin
  StartTime := Time();
  Aux := StartTime;

  ...

  while (not Answer) and (MillisecondsBetween(Aux, StartTime) < 10000) do
  begin
    Sleep(0);
    Aux := Time();
  end;

  if (not Answer) then
  begin
    ShowMessage('You have taken too much time, your turn is lost');
    Exit; //We leave the script
  end;

  ...
end;

Note that this is not really a good use for TDateTime. Your calculations are relying on the system clock in local time being accurate and unchanging, but it can be changed dynamically while your code is running (user updates, network updates, daylight saving time change, etc), throwing off the results.

Consider using TStopWatch instead. It is intended for exactly this kind of use-case (determining elapsed time between actions), eg:

uses
  ..., System.Diagnostics;

var
  SW: TStopWatch;
begin
  SW := TStopWatch.StartNew;

  ...

  while (not Answer) and (SW.ElapsedMilliseconds < 10000) do
    Sleep(0);

  if (not Answer) then
  begin
    ShowMessage('You have taken too much time, your turn is lost');
    Exit; //We leave the script
  end;

  ...
end;

Or, you could use TEvent instead, and have the answer signal the event when ready, eg:

uses
  ..., SyncObjs;

var
  AnsweredEvent: TEvent;

...

// when the answer is submitted:
AnsweredEvent.SetEvent;

...

begin
  AnsweredEvent.ResetEvent;

  ...

  if AnsweredEvent.WaitFor(10000) <> wrSignaled then
  begin
    ShowMessage('You have taken too much time, your turn is lost');
    Exit; //We leave the script
  end;
end; 

initialization
  AnsweredEvent := TEvent.Create;
finalization
  AnsweredEvent.Free;

Upvotes: 5

Related Questions