比较delphi中的日期时间

San*_*pez 2 delphi datetime pascal

我正在 Delphi 中开发一个问答游戏,我想要一个计时器,以便玩家没有无限的时间来回答问题。我正在使用“时间”函数来获取当前时间,但我不知道如何将其转换为整数之类的东西,这样当假设 10 秒过去了时,玩家就失去了机会。它看起来像这样:

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;
  
Run Code Online (Sandbox Code Playgroud)

问题是我不能在 DateTimes 中进行算术运算,据我所知,所以我需要一种不同的方法来比较 2 个不同的时间实例。任何帮助将不胜感激,谢谢!

Rem*_*eau 5

TDateTTimeTDateTime是使用浮点数实现的,因此您可以对它们执行算术运算。

但在这种情况下,你真的不应该。该DateUtils单元具有许多处理日期/时间值的功能,例如:

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;
Run Code Online (Sandbox Code Playgroud)

请注意,这对于TDateTime. 您的计算依赖于准确且不变的本地时间系统时钟,但它可以在您的代码运行时动态更改(用户更新、网络更新、夏令时更改等),从而丢弃结果。

考虑TStopWatch改用。它正好适用于这种用例(确定操作之间经过的时间),例如:

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;
Run Code Online (Sandbox Code Playgroud)

或者,您可以TEvent改为使用,并在准备好时让应答信号通知事件,例如:

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;
Run Code Online (Sandbox Code Playgroud)