* * *

Author Topic: [SOLVED] Question about FormatDateTime and TTimer  (Read 1045 times)

valford

  • New member
  • *
  • Posts: 7
[SOLVED] Question about FormatDateTime and TTimer
« on: December 31, 2017, 10:02:17 am »
Hi, I am new on this forum (and Pascal) and I want to tell you all that English is not my first language so sorry about any grammar mistake  :-[

I'm working on an application to collect data from a device and I'm using FormatDateTime to show the time elapsed since the application start data collection. However, data collection can take days and when the timer goes over 24 hours it restarts from 0 again. I have tried using different formats described here:
https://www.freepascal.org/docs-html/rtl/sysutils/formatchars.html
https://www.freepascal.org/docs-html/rtl/sysutils/formatdatetime.html
But when I use [hh] instead hh the application shows me just the time between brackets  :-\

So I am sure I am doing something wrong, could someone help me? please

Here is the detail of my code

Code: Pascal  [Select]
  1. procedure TMain.Timer2Timer(Sender: TObject);
  2. begin
  3.   Elapsed:=Elapsed+1;
  4.   if Running=True then
  5.   TNext:=TNext-1
  6.   else
  7.   TNext:=Time*60;
  8.  
  9.   Label21.caption:=FormatDateTime('hh:nn:ss',Elapsed/86400);  //I tried '[hh]:nn:ss' as well
  10.   Label23.caption:=FormatDateTime('hh:nn:ss',TNext/86400);
  11. end;

A second thing related to this: The timer in the code above has an interval of 1 second; however after some hours of works I saw that the clock get a delay. I am using in one part of my code the sleep() function, is this affecting the timer?
I am using the delay because I need wait 250-500 ms for the answer from my device when I send the query. An also the sleep() is inside of another Timer...

Here a little more context about this:

Code: Pascal  [Select]
  1. procedure TMain.Timer1Timer(Sender: TObject);
  2. var
  3. ...
  4. begin
  5.  
  6. ...
  7.  
  8.   BytesWritten := lazserial1.WriteData('SI'+chr(13) + chr (10));
  9.   sleep (500) ;
  10.   Current := lazserial1.ReadData;
  11.  
  12. ...
  13.  
  14.   end;

I will try changing sleep() function by another timer.

Code: Pascal  [Select]
  1. procedure TMain.Timer1Timer(Sender: TObject);
  2. var
  3. ...
  4. begin
  5.  
  6. ...
  7.  
  8.   BytesWritten := lazserial1.WriteData('SI'+chr(13) + chr (10));
  9.  
  10.   Timer3.Interval:= 500;
  11. ...
  12. end;
  13.  
  14.  
  15. procedure TMain.Timer3Timer(Sender: TObject);
  16. begin
  17.  
  18. ...
  19.   Current := lazserial1.ReadData;
  20.  
  21. ...
  22.  
  23. end;

However, as I said it will take hours realise if this solves the problem, so if someone knows what is going on and can guide me I will be thankful.
« Last Edit: January 03, 2018, 09:26:01 am by valford »

wp

  • Hero Member
  • *****
  • Posts: 4398
Re: Question about FormatDateTime and TTimer
« Reply #1 on: December 31, 2017, 10:49:31 am »
But when I use [hh] instead hh the application shows me just the time between brackets  :-\
If you use the syntax with the brackets then you must activate this mode by adding the parameter [fdoInterval]:

Code: Pascal  [Select]
  1. program Project1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   SysUtils;
  7.  
  8. const
  9.   dt = 1.5;   // 1 1/2 days = 24 + 12 = 36 hours
  10. begin
  11.   WriteLn(FormatDateTime('[hh]:nn:ss', dt, [fdoInterval]));
  12.   ReadLn;
  13. end.
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

valford

  • New member
  • *
  • Posts: 7
Re: Question about FormatDateTime and TTimer
« Reply #2 on: December 31, 2017, 11:29:43 am »
Thanks wp! the first problem is solved  :D

Do you know if the sleep() function can have an effect on the timer? I mean, I know the application literally sleep during that time, but when it wakes up what do it happen with timers? would it be better to use another timmer instead to use sleep() function?

taazz

  • Hero Member
  • *****
  • Posts: 5027
Re: Question about FormatDateTime and TTimer
« Reply #3 on: December 31, 2017, 01:08:27 pm »
Thanks wp! the first problem is solved  :D

Do you know if the sleep() function can have an effect on the timer? I mean, I know the application literally sleep during that time, but when it wakes up what do it happen with timers? would it be better to use another timmer instead to use sleep() function?
On windows a timer is a system task that adds a message in your application's message queue on the specified intervals. When an application calls sleep the OS will not activate your application's process  before the sleep interval has passed in which times it will process all the queued messages. On other oses I have no idea how things work.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

wp

  • Hero Member
  • *****
  • Posts: 4398
Re: Question about FormatDateTime and TTimer
« Reply #4 on: December 31, 2017, 01:19:44 pm »
Do this experiment:
  • create a new project
  • add a TTimer and a TLabel; the timer's default interval should remain at 1000 (ms).
  • in the Timer's OnTimer write this code:
Code: Pascal  [Select]
  1. procedure TForm1.Timer1Timer(Sender: TObject);
  2. begin
  3.   Label1.Caption := FormatDateTime('h:nn:ss.zzz', now);
  4.   Sleep(990);
  5. end;  

When you run this program, the label will count up the seconds in equal 1-second intervals, sometimes a few milliseconds longer. This means: the sleep time is respected in the timer interval.

But: if you try to drag the form across the screen you will feel some delayed response - this is what taazz said.

Therefore, sleep() over longer intervals is bad! You should try to run the data aquisition in a separate thread. I think (but am not sure) that lazserial is prepared for that.
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

jamie

  • Hero Member
  • *****
  • Posts: 654
Re: Question about FormatDateTime and TTimer
« Reply #5 on: December 31, 2017, 08:41:35 pm »
Why not simply use "NOW" when the app wakes up from a device event?


 There are ready made functions to calculate the days between two dates.

 PeriodBetween : for example

 HoursBetween etc..

valford

  • New member
  • *
  • Posts: 7
Re: Question about FormatDateTime and TTimer
« Reply #6 on: January 01, 2018, 04:27:01 am »
Thanks wp! the first problem is solved  :D

Do you know if the sleep() function can have an effect on the timer? I mean, I know the application literally sleep during that time, but when it wakes up what do it happen with timers? would it be better to use another timmer instead to use sleep() function?
On windows a timer is a system task that adds a message in your application's message queue on the specified intervals. When an application calls sleep the OS will not activate your application's process  before the sleep interval has passed in which times it will process all the queued messages. On other oses I have no idea how things work.

Do this experiment:
  • create a new project
  • add a TTimer and a TLabel; the timer's default interval should remain at 1000 (ms).
  • in the Timer's OnTimer write this code:
Code: Pascal  [Select]
  1. procedure TForm1.Timer1Timer(Sender: TObject);
  2. begin
  3.   Label1.Caption := FormatDateTime('h:nn:ss.zzz', now);
  4.   Sleep(990);
  5. end;  

When you run this program, the label will count up the seconds in equal 1-second intervals, sometimes a few milliseconds longer. This means: the sleep time is respected in the timer interval.

But: if you try to drag the form across the screen you will feel some delayed response - this is what taazz said.

Therefore, sleep() over longer intervals is bad! You should try to run the data aquisition in a separate thread. I think (but am not sure) that lazserial is prepared for that.

Thanks to both of you for the explanation, I thought timer work independently of the sleep(), but as you explain the timer also is under the sleepy time xD

Why not simply use "NOW" when the app wakes up from a device event?


 There are ready made functions to calculate the days between two dates.

 PeriodBetween : for example

 HoursBetween etc..


I tried HoursBetween and work perfectly, also work very well with another timer, but I think your solution is much better because does not depend on the application and may be the timer can be affected if the computer is working too hard (isn't it?)

Thanks it is solved!  :D


 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus