Recent

Author Topic: Bug with now function after DST changeover?  (Read 881 times)

AlanTheBeast

  • Sr. Member
  • ****
  • Posts: 407
  • My software never cras....
Bug with now function after DST changeover?
« on: March 09, 2025, 07:30:36 pm »

I have a background program running in Terminal.  It does various "housekeeping" things for me.
One of the things is to initiate a Time Machine backup at specific times, currently set for noon (12:00*) and evening (18:00).

Today marks the first day of DST for the year and I noticed that:

1) The TM backup occurred at 13:00 rather than 12:00

2) The displayed time in the program is lagging by 1 hour.  That is to say, when it posts an event, the time is 1 hour behind the actual time that the system displays.

The function I use to check if it is time to start a function is the "now" function (returning a TDateTime).

So - it appears that this function is flawed in that it doesn't account for DST changing while a program is active.  The description of the now function is:

"Returns the current date and time."
https://www.freepascal.org/docs-html/rtl/sysutils/now.html


( MacOS 15.3.1, iMac M3,
  Free Pascal Compiler version 3.2.2 [2021/05/16] for aarch64)

Remedy for now is to re-start the housekeeping program. [I suppose I could program that in as well (if the program halts, then a "watch" program that is running will restart it).  So I could re-start the program on the DST change day.]
_____________________________________________________
*While above I use specific times, it's actually in the period after the time above, where the function is running about 1 per minute, so the backup could start at (say) 12:00:35.234 .
Everyone talks about the weather but nobody does anything about it.
..Samuel Clemens.

cdbc

  • Hero Member
  • *****
  • Posts: 2575
    • http://www.cdbc.dk
Re: Bug with now function after DST changeover?
« Reply #1 on: March 09, 2025, 07:44:25 pm »
Hi
I use something like the following to care about 'Now':
Code: Pascal  [Select][+][-]
  1. (* anHour = 0.0834; { zulu + 0.0417 = local time ~ dk => summertime + 2 ~ 0.0834 } *)
  2. function bcNow: TDateTime;
  3. var lnow: TDateTime;
  4. begin { wintertime is only 1 hour ahead of zulu in denmark }
  5.   {$ifdef VER3_3_1} lnow:= NowUTC + anHour; {$else} lnow:= Now + anHour; {$endif}
  6.   { summertime is 2 hours ahead of zulu in denmark ~ tz+dst }
  7.   Result:= lnow + (DateIsInDST(lnow) * anHour); { func returns 0 or 1 }
  8. end; { bcNow }
I have a function that returns 0 or 1 depending on the date being inside the DST window...
You're not alone in your struggle  ;D
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6/QT6 -> FPC Release -> Lazarus Release &  FPC Main -> Lazarus Main

AlanTheBeast

  • Sr. Member
  • ****
  • Posts: 407
  • My software never cras....
Re: Bug with now function after DST changeover?
« Reply #2 on: March 09, 2025, 08:10:06 pm »
Hi
I use something like the following to care about 'Now':
Code: Pascal  [Select][+][-]
  1.  
  2. [code=pascal] {$ifdef VER3_3_1} lnow:= NowUTC + anHour; {$else} lnow:= Now + anHour; {$endif}
  3.   { summertime is 2 hours ahead of zulu in denmark ~ tz+dst }
  4.   Result:= lnow + (DateIsInDST(lnow) * anHour); { func returns 0 or 1 }
I have a function that returns 0 or 1 depending on the date being inside the DST window...
You're not alone in your struggle  ;D
Regards Benny

Thank you.

Interesting - but I'm a little confused - if I run a fresh instance of my program after the DST change, then now returns the correct (DST) time.

So your above fix is for a program running at the time the change occurs?

Also (it would appear from a quick test) I would have to install later FPC to access NowUTC and DateIsInDST(t).

(I'm still on FPC 3.2.2).
Everyone talks about the weather but nobody does anything about it.
..Samuel Clemens.

cdbc

  • Hero Member
  • *****
  • Posts: 2575
    • http://www.cdbc.dk
Re: Bug with now function after DST changeover?
« Reply #3 on: March 09, 2025, 08:24:18 pm »
Hi
You're welcome.
It adapts every time you call it, using these:
Code: Pascal  [Select][+][-]
  1. { used for daylight saving time }
  2. function LastSundayInMarch(aYear: word): TDateTime;
  3. var Dt: TIsoDate;
  4. begin
  5.   Dt:= TIsoDate.Create(24,03,aYear);
  6.   try
  7.     while Dt.DayNumber <> 7 do Dt.IncrementDay(1);
  8.     Result:= Dt.AsDate;
  9.   finally Dt.Free; end;
  10. end;
  11.  
  12. { used for daylight saving time }
  13. function LastSundayInOctober(aYear: word): TDateTime;
  14. var I: IIsoDate;
  15. begin
  16.   I:= TIsoDate.Create(24,10,aYear);
  17.   while I.DayNumber <> 7 do I.IncrementDay(1);
  18.   Result:= I.AsDate;
  19.   I:= nil;
  20. end;
  21.  
  22. { DateIsInDST returns 1 for daylight saving time, 0 for normal time 15.08.2022 /bc }
  23. function DateIsInDST(const aDateTime: TDateTime): integer;     { one could use }
  24. begin                                                   { DateTimeInRange from }
  25.   Result:= 0;                                                  { DateUtils.inc }
  26.   if (aDateTime >= LastSundayInMarch(YearOf(aDateTime))) and
  27.      (aDateTime < LastSundayInOctober(YearOf(aDateTime))) then Result:= 1;
  28. end;
It works just fine when running /over/ the change, I couldn't be bothered to remember to restart an app at specific times, what are computers for?!?  :D
Regards Benny

eta: I run both 3.2.2 and trunk, so yes that's why the 'ifdef' is there...
     NowUTC is present in trunk.
« Last Edit: March 09, 2025, 08:26:46 pm by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6/QT6 -> FPC Release -> Lazarus Release &  FPC Main -> Lazarus Main

AlanTheBeast

  • Sr. Member
  • ****
  • Posts: 407
  • My software never cras....
Re: Bug with now function after DST changeover?
« Reply #4 on: March 09, 2025, 08:53:26 pm »

Thanks cdbc.  I'll review all that and implement it in some way.
Everyone talks about the weather but nobody does anything about it.
..Samuel Clemens.

dbannon

  • Hero Member
  • *****
  • Posts: 3647
    • tomboy-ng, a rewrite of the classic Tomboy
Re: Bug with now function after DST changeover?
« Reply #5 on: March 10, 2025, 01:34:07 am »
I use -

Code: Pascal  [Select][+][-]
  1.     {$ifdef LINUX}
  2.     ReReadLocalTime();    // in case we are near daylight saving time changeover
  3.     {$endif}
  4.     ThisMoment:=Now;
     

The ReReadLocalTime() is in the Unix unit, looks like my $ifdef should say "Unix" rather than "Linux"   :(

Davo
Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

AlanTheBeast

  • Sr. Member
  • ****
  • Posts: 407
  • My software never cras....
Re: Bug with now function after DST changeover?
« Reply #6 on: March 10, 2025, 02:14:22 pm »
I use -

Code: Pascal  [Select][+][-]
  1.     {$ifdef LINUX}
  2.     ReReadLocalTime();    // in case we are near daylight saving time changeover
  3.     {$endif}
  4.     ThisMoment:=Now;
     

The ReReadLocalTime() is in the Unix unit, looks like my $ifdef should say "Unix" rather than "Linux"   :(

That's interesting.  If I understand:
https://www.freepascal.org/docs-html/rtl/unixutil/epochtolocal.html

... I'll just add it to an existing function that runs once per hour, and it should take care of the issue in the future.

I don't bother with the portability directives, this is "hobby" code for my computer alone.

Thanks!
Everyone talks about the weather but nobody does anything about it.
..Samuel Clemens.

 

TinyPortal © 2005-2018