Lazarus

Programming => Operating Systems => Linux => Topic started by: jollytall on August 23, 2021, 08:49:42 pm

Title: Now function gives back wrong time
Post by: jollytall on August 23, 2021, 08:49:42 pm
I have the simplest program:
Code: Pascal  [Select][+][-]
  1. program nowprogram;
  2. uses  SysUtils;
  3. begin
  4.   writeln(DateTimeToStr(Now));
  5. end.  
I run it on two different machines, both with Debian 10, in the same timezone, with NTP, etc. Still one gives the correct time, the other gives one hour more. I could not figure out what can go wrong.

A bit of background: I wanted to get back the TZ offset for IdGlobal Indy, what is not implemented under Linux. I found (see few post below) a LazUtils utility and a function NowUTC that gives back the UTC time. So I ran it (Now-NowUTC) and got the wrong result. I thought first that the new and complex NowUTC is the guilty one, but it turned out that that is correct and the basic Now is wrong.
(I have the TZ set correctly, but actually that does not matter, even if it were set to anywhere, Now should give back the local time, seen in the OS GUI.)
Title: Re: Now function gives back wrong time
Post by: winni on August 23, 2021, 09:34:16 pm
Hi!

One of your Debian is allowed to behave like a Windows machine and set the time to the local TimeZone.

The other machine behaves in the standard Unix/Linux mode: the clock is set to UTC.


In my eyes the first is a misconfiguration.

Anyway: In the unit  LazSysutils exists the function

Code: Pascal  [Select][+][-]
  1. function NowUTC: TDateTime;


And there  is the package Pascal TimeZones. Read more:

https://wiki.freepascal.org/PascalTZ (https://wiki.freepascal.org/PascalTZ)


Winni


PS.:

How to Set or Change Timezone on Debian 10:

https://linuxize.com/post/how-to-set-or-change-timezone-on-debian-10/ (https://linuxize.com/post/how-to-set-or-change-timezone-on-debian-10/)
Title: Re: Now function gives back wrong time
Post by: MarkMLl on August 23, 2021, 09:36:34 pm
I've not seen that on Debian, and a year or so ago I did a lot of prodding at different ways of getting time information and reconciling seconds-since-epoch etc.

However I would say that I don't think much of the way that Now() returns something which is basically a 64-bit floating-point number, since the further we move from the epoch the fewer bits are available for the fractional part. And I /know/ that that's graven in stone due to Delphi etc., and I /still/ don't think much of it: at the very least the calculations should try to use the platform-specific extended type internally.

MarkMLl
Title: Re: Now function gives back wrong time
Post by: winni on August 23, 2021, 09:50:19 pm
Hi!

I have seen a lot of misconfigured Debian machines concerning the timezones.
Just had a fresh setup Debian machine some days ago which was one hour away. Everything setup by default.

As the TDateTime is a Double you can compute with dates in every way.
But be warned of the Delphi-compatible converting functions. There is a lot of nonsens.

If
Date1 -Date2

is in th range of 0..99 days then Delphi/Lazarus adds the year 1900.

And a lot of other rubbish.

Write the convert functions yourself.

Basic unit is: A day is One.
An hour is 1/24
A minute is 1/(24*60)
A second is 1/(24*60*60);

The rest is trivial.

Winni





Title: Re: Now function gives back wrong time
Post by: jollytall on August 23, 2021, 10:03:57 pm
@winni
The two systems are set-up as much as possible the same way. timedatectl command in Linux gives exactly the same result for all the values. Also ls -l /etc/localtime gives the same and correct timezone on both machines. It is true that some time back I changed timezones on the "bad" machine, but at the moment I do not see any difference. Where can I check if my Linux really thinks in a "Windows way" and how can I change it?
If it is so, shouldn't the bad machine give back the UTC as the local time? It is not the case. The local time is UTC + 0200, while the misbehaving machine gives UTC + 0300. Furthermore it is not even the non-DST, as that would be UTC + 0100.
I do not understand what you mean with NowUTC. As I wrote, I know it and use it, and that gives a correct time on both machines. I need both Now and NowUTC as the easiest way to know the offset (Now-NowUTC).
I still do not see how Now() can give something else than the local time.

@MarkMLI
I do not think it is a number format, bitlength error. It gives the correct minute/second just one hour wrong.

@winni (2)
Thanks, but the calculation is correct. It is simply Now() being wrong.
Where can you see that your system is one hour away? I can have the same problem, but as said above, I do not see anything wrong.
Title: Re: Now function gives back wrong time
Post by: winni on August 23, 2021, 10:22:32 pm
Hi!

Strange.

The simplest way is using the bash:

This gives you the local time:

Code: Bash  [Select][+][-]
  1. date

And this tells you the UTC
Code: Bash  [Select][+][-]
  1. date -u

My correct result is there are 2 hours difference:

1 for Central Europe an 1 for daylight saving.

Winni
Title: Re: Now function gives back wrong time
Post by: winni on August 23, 2021, 10:32:37 pm
To demonstrate the old Delphi nonsense which Lazarus uses we show very simple code

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var date1,date2: TDateTime;
  3. begin
  4. date1  := EncodeDate(2021,8,1);
  5. Date2 := encodeDate (2021,8,15);
  6. showMessage (DateToStr(Date1-Date2) + LineEnding + DateToStr(Date2-Date1) );
  7. end;            


This results ins

16-12-99
13-1-00

But don't tell the headquater this is nonsense.

It is not because it is Delphi compatible!!

Winni
Title: Re: Now function gives back wrong time
Post by: jollytall on August 23, 2021, 10:40:18 pm
Here are two screenshots. The same commands, same "nowprogram", different results.

I understand the Delphi nonsense, but in these examples there is no difference, only plain Now().
Title: Re: Now function gives back wrong time
Post by: winni on August 23, 2021, 10:42:03 pm
Hi!

Use  timedatectl on the bash. And compare if the two machines give the same result.

In my case it results in:

Code: Bash  [Select][+][-]
  1. timedatectl
  2.                Local time: Mon 2021-08-23 22:38:55 CEST
  3.            Universal time: Mon 2021-08-23 20:38:55 UTC
  4.                  RTC time: Mon 2021-08-23 20:38:56
  5.                 Time zone: Europe/Berlin (CEST, +0200)
  6. System clock synchronized: yes
  7.               NTP service: active
  8.           RTC in local TZ: no
  9.  


Winni

Title: Re: Now function gives back wrong time
Post by: jollytall on August 23, 2021, 10:54:23 pm
Winni,
As said above:
timedatectl command in Linux gives exactly the same result for all the values. Also ls -l /etc/localtime gives the same and correct timezone on both machines.
Theses were the first two things I checked and both give the same and correct results, just like date and date -u.
The only thing that gives a different result is the one line pascal program in the OP.
Title: Re: Now function gives back wrong time
Post by: winni on August 23, 2021, 11:03:42 pm
Hi!

Stange, strange, ...

Somewhere a bit in the RAM hit by hard rays from the sun?
Happens with every PC 6 times in 24 hours.
Most times nothing realy important is change: A bit in unused space, a pixel in an Icon,  an unexspected keypress, and and...

But sometimes it can result in such a strange thing.

I've got no other idea: reboot both machines.

If the problems persists then we have a hard job.

Winni
Title: Re: Now function gives back wrong time
Post by: winni on August 23, 2021, 11:14:32 pm
Hi!

And one Debian is a RasPi???

Andreas from Vienna had the same problem:

https://forum.lazarus.freepascal.org/index.php?topic=47317.0
 (https://forum.lazarus.freepascal.org/index.php?topic=47317.0)

I don't know nothing about kindergarden computers.

Winni
Title: Re: Now function gives back wrong time
Post by: jollytall on August 23, 2021, 11:20:14 pm
Well, it is under the table, so not much sun :-)

But anyway I have just restarted it and got the same error:

Code: Bash  [Select][+][-]
  1. $ timedatectl
  2.                Local time: Mon 2021-08-23 23:08:40 CEST
  3.            Universal time: Mon 2021-08-23 21:08:40 UTC
  4.                  RTC time: Mon 2021-08-23 21:08:40
  5.                 Time zone: Europe/Budapest (CEST, +0200)
  6. System clock synchronized: yes
  7.               NTP service: active
  8.           RTC in local TZ: no
  9. $ ./nowprogram
  10. 24-8-21 00:08:45

The only difference, though it should not matter that the program is compiled once on the good machine and copied to the bad one. Can it link a library not compatible with the other??? I don't think so. If not likely, I would not start installing Lazarus on it.

@latest post
I had read earlier the rPi problem when searched the forum, but it is not a rPi (anyway that is because rPi has no battery clock, so until it is not set/synchronised it does not know the time). Mine is a 64bit desktop (bad one) and a 64 bit laptop (good one). So, again, the program is the same on binary level, not a different compile from the same source.
Title: Re: Now function gives back wrong time
Post by: MarkMLl on August 23, 2021, 11:29:02 pm
And one Debian is a RasPi???

Andreas from Vienna had the same problem:

https://forum.lazarus.freepascal.org/index.php?topic=47317.0
 (https://forum.lazarus.freepascal.org/index.php?topic=47317.0)

I don't know nothing about kindergarden computers.

Shouldn't make a difference. The only detail is that the RPi's kernel doesn't have a valid time until it's been able to get one using NTP, ... ... that could I suppose impact the detail of DST correction if the kernel's trying to get some configuration detail from non-existent BIOS CMOS.

MarkMLl
Title: Re: Now function gives back wrong time
Post by: sstvmaster on August 23, 2021, 11:33:41 pm
Can you try to remove the bios battery or set the bios clear jumper? Or maybe bios update helps?
Title: Re: Now function gives back wrong time
Post by: winni on August 23, 2021, 11:34:46 pm
Hi!

The good, the bad and the ugly .....
Nice song.

So we have to solve this ugly problem.

a) Same hardware concerning the proc? (AMD/Intel)
b) Same Debian version ??
b) Same fpc and Lazarus version??


And there are there problems with the different time servers in Debian

Some days ago I set up a new Debian 10 machine.
I had problems with ntpd and Debians timesyncd.
They where fighting against each other.
I disabled both and call now my old  ntpdate-script from cron.

I don't  know what's realy the problem with ntpd and timesyncd
I was just botherd and did it "the old way".

Winni
Title: Re: Now function gives back wrong time
Post by: jollytall on August 24, 2021, 12:02:45 am
@sstvmaster
I will try that tomorrow.

@winni
a) Same hardware concerning the proc? (AMD/Intel)
b) Same Debian version ??
b) Same fpc and Lazarus version??

a. Different HW. Working Intel, wrong AMD.
b. Yes: Debian GNU/Linux 10 (buster)
b. (or c.) N/A. As said above there is no compiler on the bad one. The binary is moved over, not compiled on that machine.

Regarding how Linux synchronizes, I am not sure. Where can I check it?
Title: Re: Now function gives back wrong time
Post by: winni on August 24, 2021, 12:18:35 am
Hi!

ntpd has a manpage on every linux machine:

Code: Bash  [Select][+][-]
  1. man ntpd
  2.  


Do it on your own with the bash:

Code: Pascal  [Select][+][-]
  1. ntpdate ntp1.ptb.de
  2.  

Time from german "Time Headquarter" in Braunschweig.

I don't know about timesyncd. No Debian at hand now.

Winni
Title: Re: Now function gives back wrong time
Post by: Remy Lebeau on August 24, 2021, 01:51:37 am
I wanted to get back the TZ offset for IdGlobal Indy, what is not implemented under Linux.

In what regard? Because for the most part, Indy now relies on FreePascal's time conversions rather than its own, so make sure you are using an up-to-date version.  If you are referring to the GOffsetFromUTC variable, that has been deprecated and is no longer used on systems where FreePascal provides its own GetLocalTimeOffset().
Title: Re: Now function gives back wrong time
Post by: jollytall on August 24, 2021, 09:14:02 am
OK, so an update on many replies (thanks for all of them).

@sstvmaster
I removed the battery for like 15 minutes. After that and with no network connection I restarted it. It had the last known time. My little program gave +1 hour compared to that. Once the network was reconnected the time synchronized to the correct one and my program gave +1 hour compared to that. So, in short, nothing changed.
Regarding Bios update, I would leave it out, for the time being. I would assume that Now() should call some OS functions and in the OS everything seems fine, so it is unlikely to have a Bios problem (and not even sure it has a more recent update).

@winni
It seems I do not have ntpd installed on any of the machines. no man page, no working command. So, probably it is timesyncd, although that is over my competency level.
Anyway the battery removal action clearly showed that the synchronization works well, as the time was updated once the network was reconnected.

@Remy
Thanks for joining in. Yes, I might not use the latest Indy. This is why I did not open an Indy specific question, did not want to complain on something where I did not doi the full homework before.
If Now() worked (as it works on one of the machines), I do not have a problem with Indy. Nonetheless, as you asked, here is what I did:
I have Indy 10.2.0.3 installed. I tried to look for a full packaged later version downloadable, but could not find. I went to https://wiki.freepascal.org/Indy_with_Lazarus (https://wiki.freepascal.org/Indy_with_Lazarus), that took me to https://www.indyproject.org/ (https://www.indyproject.org/), in it Download, Indy10. There are three links - none of them works.
In the installed 10.2.0.3 under /fpc, there was IdGlobal.pas with a function OffsetFromUTC, but that did not have a Linux defined source at all (and so the sw crashed when a NaN was handed over to the next function). So, I went on Github and found https://github.com/IndySockets/Indy/blob/master/Lib/System/IdGlobal.pas (https://github.com/IndySockets/Indy/blob/master/Lib/System/IdGlobal.pas). I just replaced the installed OffsetFromUTC function (blame me, not the whole IdGlobal) to the Github version. This one goes on
Code: Pascal  [Select][+][-]
  1. Result := GOffsetFromUTC;
for Linux, what is set to 0 some lines earlier. So I replaced this line with
Code: Pascal  [Select][+][-]
  1. Result := Now - nowUTC;
after adding LazSysUtils to uses, and it works like a charm when Now gives the correct time.
If you can guide me to a better solution, I would appreciate it, however that still does not solve the Now issue that causes problems elsewhere as well, outside Indy.
Title: Re: Now function gives back wrong time
Post by: Remy Lebeau on August 24, 2021, 05:40:31 pm
Yes, I might not use the latest Indy.
I have Indy 10.2.0.3 installed.

That is an EXTREMELY OLD version.  You really need to upgrade.  The current version of Indy in FreePascal/Lazarus' OPM (https://wiki.freepascal.org/Online_Package_Manager) is 10.6.2.3911.

I tried to look for a full packaged later version downloadable, but could not find.

Indy is in OPM.  Or, you can download from Indy's GitHub repo (https://github.com/IndySockets/Indy/) directly.

I went to https://wiki.freepascal.org/Indy_with_Lazarus (https://wiki.freepascal.org/Indy_with_Lazarus), that took me to https://www.indyproject.org/ (https://www.indyproject.org/), in it Download, Indy10. There are three links - none of them works.

Known issue:

https://www.indyproject.org/2021/02/10/links-to-old-indy-website-pages-are-currently-broken/

In the installed 10.2.0.3 under /fpc, there was IdGlobal.pas with a function OffsetFromUTC, but that did not have a Linux defined source at all (and so the sw crashed when a NaN was handed over to the next function).

That was fixed a LONG time ago.  And then updated again more recently with new functionality.

So, I went on Github and found https://github.com/IndySockets/Indy/blob/master/Lib/System/IdGlobal.pas (https://github.com/IndySockets/Indy/blob/master/Lib/System/IdGlobal.pas). I just replaced the installed OffsetFromUTC function (blame me, not the whole IdGlobal) to the Github version. This one goes on
Code: Pascal  [Select][+][-]
  1. Result := GOffsetFromUTC;
for Linux

You really should not cherry-pick individual files, as there are a lot of cross-file dependencies.  But, at the very least, make sure you update IdCompilerDefines.inc as well, which most Indy units refer to.  It defines a lot of conditionals related to FreePascal, in this particular case, it defines HAS_GetLocalTimeOffset for FPC 2.6.2 and higher, which OffsetFromUTC() in IdGlobal.pas looks at:

IdCompilerDefines.inc
Code: Pascal  [Select][+][-]
  1. ...
  2. {$IFDEF FPC}
  3.   ...
  4.   {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20602)}
  5.     {$DEFINE FPC_2_6_2_OR_ABOVE}
  6.   {$IFEND}
  7.   ...
  8. {$ENDIF}
  9. ...
  10. {$IFDEF FPC}
  11.   ...
  12.   {$IFDEF FPC_2_6_2_OR_ABOVE}
  13.     ...
  14.     {$DEFINE HAS_GetLocalTimeOffset}
  15.     ...
  16.   {$ENDIF}
  17.   ...
  18. {$ENDIF}
  19. ...
  20.  

IdGlobal.pas
Code: Pascal  [Select][+][-]
  1. function OffsetFromUTC: TDateTime;
  2. ...
  3. begin
  4.   ...
  5.   {$IFDEF HAS_GetLocalTimeOffset}
  6.   // RLebeau: Note that on Linux/Unix, this information may be inaccurate around
  7.   // the DST time changes (for optimization). In that case, the unix.ReReadLocalTime()
  8.   // function must be used to re-initialize the timezone information...
  9.   Result := GetLocalTimeOffset() / 60 / 24;
  10.   {$ELSE}
  11.   ...
  12.   {$ENDIF}
  13. end;

As I said earlier, Indy should not be using the global GOffsetFromUTC variable anymore on most platforms.
Title: Re: Now function gives back wrong time
Post by: jollytall on August 24, 2021, 08:01:39 pm
Thanks. I installed as you wrote and now, after a quick check everything seem to work (in Indy! - the original Now() problem is not solved from this).
Few questions, comments:
- Honestly I never used the OPM, because to me that is "too" Lazarus. Most of my programs are terminal ran or daemons, so try to avoid visual components. So, I use most components (not only Indy, but e.g. SQL too) with .Create() and not through adding an icon to the form, Object Inspector, etc. Indy is especially heavy in terms of components in the Components bar. This is why I had it on my machine, but was not installed as a Lazarus package. Now I have it as a package. Can it be removed and still used? Then, I guess, I cannot use the Project/Inspector/Required packages. So, is the solution to add the folder (hidden - see later) to Project/Options/Compiler/Path/Other Units?
- Now as I know how to install it, I went back and tried to find it on the Indy website, but still could not find. It is a petty that such a great piece of software is so difficult to find (at least for me).
- The earlier installed Indy-s (and other packages) are under /usr/share/lazarus/components. Within indy-10.2.0.3 there, I had separate directories for /fpc and for /lazarus with similar, or identical units. Earlier I had added the ..../fpc to my Path and used it like that (thought the /lazarus ones are for the LCL). Now, I could hardly find the installed package and the units as they are under ~/.lazarus/onlinepackagemanager/packages/indy10, a private, hidden directory. There I do not see a separate /fpc and /lazarus version. Is that normal? Shouldn't the whole package (and also the lazarus binary) be under a shared and visible directory? Did I do something incorrectly?
- Although the files are probably the latest versions (IdGlobal is just as you described), but the change log is still very old, e.g. for IdGlobal it says Rev 1.54 2/9/2005. Does it mean that the file level change log is not maintained anymore?
Title: Re: Now function gives back wrong time
Post by: Remy Lebeau on August 24, 2021, 09:29:35 pm
- Honestly I never used the OPM, because to me that is "too" Lazarus. Most of my programs are terminal ran or daemons, so try to avoid visual components. So, I use most components (not only Indy, but e.g. SQL too) with .Create() and not through adding an icon to the form, Object Inspector, etc. Indy is especially heavy in terms of components in the Components bar. This is why I had it on my machine, but was not installed as a Lazarus package. Now I have it as a package. Can it be removed and still used? Then, I guess, I cannot use the Project/Inspector/Required packages. So, is the solution to add the folder (hidden - see later) to Project/Options/Compiler/Path/Other Units?

I can't really answer that, as I'm not a FPC/Lazarus user myself.  I just write code to make sure Indy is compatible with FreePascal.  Installation is a whole separate thing from me.

- Now as I know how to install it, I went back and tried to find it on the Indy website, but still could not find. It is a petty that such a great piece of software is so difficult to find (at least for me).

The site is currently broken. Did you read the link I posted earlier?

https://www.indyproject.org/2021/02/10/links-to-old-indy-website-pages-are-currently-broken/

- The earlier installed Indy-s (and other packages) are under /usr/share/lazarus/components. Within indy-10.2.0.3 there, I had separate directories for /fpc and for /lazarus with similar, or identical units. Earlier I had added the ..../fpc to my Path and used it like that (thought the /lazarus ones are for the LCL). Now, I could hardly find the installed package and the units as they are under ~/.lazarus/onlinepackagemanager/packages/indy10, a private, hidden directory. There I do not see a separate /fpc and /lazarus version. Is that normal? Shouldn't the whole package (and also the lazarus binary) be under a shared and visible directory? Did I do something incorrectly?

I can't answer that.  I don't know how OPM is setup to work.

- Although the files are probably the latest versions (IdGlobal is just as you described), but the change log is still very old, e.g. for IdGlobal it says Rev 1.54 2/9/2005. Does it mean that the file level change log is not maintained anymore?

That is correct.  It is a remnant from a Version Control system that Indy no longer uses.  Before GitHub, Indy used SVN, and before SVN it used TeamCoherence.  TC stored changelogs directly in source files.  SVN and GitHub do not.
Title: Re: Now function gives back wrong time
Post by: jollytall on August 25, 2021, 11:47:53 am
Thanks Remy,

The site is currently broken. Did you read the link I posted earlier?

Yes, I did that page, but not the archive.org links from thereon. Now I read those as well, and indeed found a reference to the OPM, so as always, it is my fault. Still, IMHO this great package would deserve some easier/more explained access and more publicity. Also, some explanation how to use it in pure FPC. I understand that you do not work on that part, but someone might know.

Would it make sense to remove one day all the old change logs, or are those still needed? I found it really misleading when I tried to understand what changed where.
Title: Re: Now function gives back wrong time
Post by: Remy Lebeau on August 25, 2021, 06:51:45 pm
Still, IMHO this great package would deserve some easier/more explained access and more publicity.

Obviously, but finding the necessary manpower to do it has always been a problem.

Also, some explanation how to use it in pure FPC. I understand that you do not work on that part, but someone might know.

https://wiki.freepascal.org/Indy_with_Lazarus ?

Would it make sense to remove one day all the old change logs

Probably.  Or at least add a final entry to each one to indicate that they are old logs and that newer logs are available in the current Version Control's history.

or are those still needed?

Well, it is never fun to lose history.  The source level changelogs predate Indy's use of SVN. The SVN logs were migrated into GitHub, so the full change history going back to 2008 is available in GitHub's history, and then the source level changelogs go back further to about 2002.  That is not long after Indy's predecessor, Winshoes, was rebranded as Indy (2000), and Indy 9 started using Version Control via TeamCoherence (2002).  Indy 10 was first released in 2005 (though it was discussed in forums for a couple of years before that).

I found it really misleading when I tried to understand what changed where.

You are not the first, likely won't be the last.
Title: Re: Now function gives back wrong time
Post by: jollytall on September 07, 2021, 05:26:55 pm
And finally it is solved. I should have thought of it earlier. I just changed the Linux timezone to something else and again back to the same what it was. In Linux everything looks the same as before. And the MAGIC, now it gives the right time in Pascal as well.
Title: Re: Now function gives back wrong time
Post by: marcov on September 07, 2021, 10:03:45 pm
But don't tell the headquater this is nonsense.

It is not because it is Delphi compatible!!

It is nonsense because a difference of dates is not a date but a timespan
TinyPortal © 2005-2018