-1

I am trying to make a countdown timer, the idea is to set the time in text edit property and after i click set timer(button), that time to be sent to Label, which will then start the countdown to 0. I have gotten to this part, but i cant figure out a way to make seconds countdown, If any of you guys can help I would appreciate it.

I tried this from an example I found online but it didnt work because this is Firemonkey application.

dec(TotalTime); {decrement the total time counter}


// Timer code..
procedure TForm1.ButtonSetTimerClick(Sender: TObject);
var
 GetTime : TDateTime;
begin
 Timer3.Enabled := True;
 Label11.Text := Edit1.Text;
 ButtonSetTimer.Enabled := False;
 Edit1.Enabled := False;
 GetTime := StrToTime(Edit1.Text);

end;

procedure TForm1.ButtonStopTimerClick(Sender: TObject);
begin
 Timer3.Enabled := False;
 ButtonSetTimer.Enabled := True;
 Edit1.Enabled := True;
end;

procedure TForm1.Timer3Timer(Sender: TObject);
var
 GetTime : TDateTime;
 Hour, Min, Sec, MSec: Word;
begin

 DecodeTime(GetTime, Hour, Min, Sec, Msec);
 Label11.Text := TimeToStr(GetTime);
 Label11.Text := IntToStr(Hour)  + ':'+ IntToStr(Min) + ':'+ IntToStr(Sec);
 Label11.Text := Format('%2.2u:%2.2u:%2.2u',[Hour,Min,Sec]);
end;

Cheers.

Ken White
  • 123,280
  • 14
  • 225
  • 444
Luka Sinobad
  • 23
  • 1
  • 2
  • 5
  • I removed the `countdowntimer` tag, because the tag description clearly says that it applies only to the Android countdowntimer class, and explicitly says that the tag should **not be used** for questions that are not directly about that class. Please read the tag descriptions before using them, and only apply tags that actually apply to your question, and do not just add any old tag because it sounds similar or you recognize the words. Tags here have *specific* meanings. – Ken White Jan 28 '15 at 16:39
  • Also, what part of that code doesn't work on FireMonkey? FMX contains a `TTimer` class, and all of your date/time related functions are part of the RTL and are not platform-specific. – Ken White Jan 28 '15 at 16:41

2 Answers2

2

You did not say how (in which format) the time is to be entered in the TEdit, so here are three alternative time entry possibilities. The output is anyway formatted as H:M:S.

I modified the code from yesterday to use TryStrToInt / TryStrToTime to catch errors. Also, a Seconds counter together with OnTimer event as in my previous example has a poor accuracy and can drift several seconds within 5 minutes. Edijs solution to compare Now with a calculated end time is insensitive to the inaccuracy of OnTimer events, so I adopted that too.

var
  TimeOut: TDateTime;

function SecsToHmsStr(ASecs: integer):string;
begin
  Result := Format('%2d:%2.2d:%2.2d',
    [ASecs div 3600, ASecs mod 3600 div 60, ASecs mod 3600 mod 60]);
;end;

procedure TForm6.Timer1Timer(Sender: TObject);
begin
  Label1.Caption := SecsToHmsStr(SecondsBetween(Now, TimeOut));
  if Now > Timeout then Timer1.Enabled := False;
end;

Time entry alternative one, Timeout after a given number of seconds

// Timeout after a given number of seconds
procedure TForm6.Button1Click(Sender: TObject);
var
  Seconds: integer;
begin
  if TryStrToInt(Edit1.Text, Seconds) then
  begin
    TimeOut := IncSecond(Now, Seconds);
    Timer1.Enabled := True;
    Label1.Caption := SecsToHmsStr(SecondsBetween(Now, TimeOut));
  end
  else
    ShowMessage('Error in number of seconds');
end;

Time entry alternative two, Timeout after a given number of hours, minutes and seconds

// Timeout after a given number of hours, minutes and seconds
procedure TForm6.Button2Click(Sender: TObject);
begin
  if TryStrToTime(Edit1.Text, TimeOut) then
  begin
    TimeOut := Now + TimeOut;
    Timer1.Enabled := True;
    Label1.Caption := SecsToHmsStr(SecondsBetween(Now, TimeOut));
  end
  else
    ShowMessage('Error in time format');
end;

Time entry alternative three, Timeout at a given time within 24 hours

// Timeout at a given time within 24 hours
procedure TForm6.Button3Click(Sender: TObject);
begin
  if TryStrToTime(Edit1.Text, TimeOut) then
  begin
    if TimeOut <= Time then
      TimeOut := Tomorrow + TimeOut
    else
      TimeOut := Today + TimeOut;
    Timer1.Enabled := True;
    Label1.Caption := SecsToHmsStr(SecondsBetween(Now, TimeOut));
  end
  else
    ShowMessage('Error in time format');
end;
Tom Brunberg
  • 20,312
  • 8
  • 37
  • 54
0

This should do it:

Uses
  System.DateUtils;

type
..
private
  FDateTimeTo: TDateTime;
end;

function IntToTimeStr(const ASeconds: Int64): string;
begin
  Result := Format('%2d:%2.2d:%2.2d', [ASeconds div 3600, ASeconds mod 3600 div 60,
    ASeconds mod 3600 mod 60]);
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  FDateTimeTo := StrToDateTime(FormatDateTime('yyyy' + FormatSettings.DateSeparator + 'mm' +
    FormatSettings.DateSeparator + 'dd 00:00:00', Now)) + StrToTime(Edit1.Text);

  if CompareDateTime(Now, FDateTimeTo) = 1 then
    FDateTimeTo := IncDay(FDateTimeTo);
end;

procedure TfrmMain.Timer1Timer(Sender: TObject);
begin
  Label1.Caption := IntToTimeStr(SecondsBetween(Now, FDateTimeTo));
end;

The result

Edijs Kolesnikovičs
  • 1,627
  • 3
  • 18
  • 34
  • Label1.Caption := FloatToTimeStr(SecondsBetween(Now, _Later)); is giving me 'missing operator or semicolon error'. I added System.DateUtils, FloatToTimeStr : string; but it only gives me that one error. – Luka Sinobad Jan 27 '15 at 19:26
  • Doesn't look good. If eTime.Text is the initial value, time zero is never reached. SecondsBetween returns Int64, not extended. The conversion from seconds to H:M:S string is very inefficient with all those string conversions back and forth. Ever heard about `div` and `mod`? – Tom Brunberg Jan 27 '15 at 20:57
  • Tom, did diagnostics, indeed, using div and mod is faster. – Edijs Kolesnikovičs Jan 28 '15 at 06:35
  • @Edijs Better, if I may say, but why are you still using the ugly assignment of `_Later`? – Tom Brunberg Jan 28 '15 at 15:11
  • @Edijs What I meant is the string manipulations. Otherwise ok, IMHO. – Tom Brunberg Jan 28 '15 at 18:06
  • Thank you for your effort, the fact that it is a Firemonkey application makes this tougher, it doesnt seem to work. Thanks again.. – Luka Sinobad Jan 28 '15 at 20:34