Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
123 views
in Technique[技术] by (71.8m points)

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!

question from:https://stackoverflow.com/questions/66053326/comparing-datetimes-in-delphi

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...