Page 1 of 1

getSystemTime() gives different results on different devices

Posted: Wed Apr 28, 2021 9:23 am
by Ats
It's roughly 11:20 in France. Here's what getSystemTime() returns on different systems:

Windows: 40809
It's the number of seconds since midnight.

Linux: 0
This one doesn't work at all...

Android: 1619601608
This one is an epoch timestamp, which is the best of the three.

Re: getSystemTime() gives different results on different devices

Posted: Wed Apr 28, 2021 12:51 pm
by VilleK
I guess it needs a SDL function to return something on Linux. And yes ideally it would return the same units on all platforms.

Re: getSystemTime() gives different results on different devices

Posted: Wed Apr 28, 2021 1:46 pm
by Ats
I don't think there's something on SDL to retrieve a timestamp. The closest thing would be SDL_GetTicks, which isn't awesome compared to the uses of Unix timestamp (ex: a daily event...)

Doesn't Pascal have everything needed to handle Timestamp?
https://www.freepascal.org/docs-html/rt ... tines.html

It seems to be used in tools/SynGen/SynGenUnit.pas : TFrmMain.OutFileCreate

Re: getSystemTime() gives different results on different devices

Posted: Fri Apr 30, 2021 7:15 am
by Ats
I took a better look at the code and the results on different platforms make sense :lol:

Windows:

Code: Select all

function Platform_GetSystemTime : integer;
var
  T : TSystemTime;
begin
  GetLocalTime(T);
  Result := T.wHour * 3600 + T.wMinute * 60 + T.wSecond;
end;
SDL (Linux?):

Code: Select all

function Platform_GetSystemTime : integer;
begin
  //TODO: System time support
  Result := 0;
end;
Mac:

Code: Select all

function Platform_GetSystemTime : integer;
begin
  Result := 0;
end;
Android:

Code: Select all

function Platform_GetSystemTime : integer;
var
  timerTimeVal : TimeVal;
begin
  gettimeofday( @timerTimeVal, nil );
  Result := timerTimeVal.tv_sec;
end;
sysutils is said to be implemented on all supported platforms:
http://www.math.uni-leipzig.de/pool/tut ... 0000000000

Why not directly using this?
function Date: TDateTime;
function DateTimeToTimeStamp( DateTime: TDateTime):TTimeStamp;

Or that one?
function DateTimeToUnix(const AValue: TDateTime): Int64;

Re: getSystemTime() gives different results on different devices

Posted: Fri Apr 30, 2021 8:49 am
by Ats
I just tried this, which is working nicely on all systems:

Code: Select all

uses SysUtils

...

function Platform_GetSystemTime : longword
var
   sysTime: TDateTime;
begin
   sysTime := Date();
   Result := Round(sysTime - 25569) * 86400;
end;
From response n°2 (10x faster than dateutils version): https://stackoverflow.com/questions/442 ... hi/4420209

Edit:
Maybe it's a bit too fast as I get:
1619740800 on linux (Friday 30 April 2021 00:00:00)
1619773302 on android (Friday 30 April 2021 09:01:42)
when I launch the two tests at the same time

Re: getSystemTime() gives different results on different devices

Posted: Fri Apr 30, 2021 9:29 am
by Ats

Code: Select all

uses SysUtils, DateUtils

...function Platform_GetSystemTime : longword;
var
  sysTime: TDateTime;
begin
  sysTime := Date();
  Result := DateTimeToUnix(sysTime);
end;
Is also returning 1619740800 on linux :roll:
I also tried with sysTime := Now;

Re: getSystemTime() gives different results on different devices

Posted: Fri Apr 30, 2021 3:05 pm
by Ats
I wrote a little pascal test:

Code: Select all

program SystemTime;

uses crt, SysUtils, DateUtils;

var
	sysTime: TDateTime;
	timeStamp: TTimeStamp;
begin
	sysTime := Date();
	writeln(sysTime);
	writeln(DateTimeToUnix(sysTime));
	writeln(Round(sysTime - 25569) * 86400);
	writeln(DateTimeToStr(Date));
	timeStamp := DateTimeToTimeStamp(Date);
	writeln(timeStamp.Time);
end. 
Which returns:
4.4316000000000000E+004
1619740800
1619740800
30-4-21
0

I don't understand why there are no hours, minutes and seconds on Linux...

Re: getSystemTime() gives different results on different devices

Posted: Fri Apr 30, 2021 3:18 pm
by Ats
All right, got it. I forgot the () after Now in my previous tests...

Code: Select all

program SystemTime;

uses crt, SysUtils, DateUtils;

var
	sysTime: TDateTime;
begin
	sysTime := Now();
	writeln(DateTimeToUnix(sysTime));
end. 
And it should work everywhere (only tested linux and android).
Should we replace each and every Platform_GetSystemTime functions, or is it better to just make one function for all the systems?

Re: getSystemTime() gives different results on different devices

Posted: Sat May 01, 2021 12:21 pm
by VilleK
Sound like a good idea for SDL and Android targets at least. For Windows I'd like to use as little of the Delphi RTL as possible for size reasons.

Re: getSystemTime() gives different results on different devices

Posted: Sat May 01, 2021 2:14 pm
by rrTea
For Windows I'd like to use as little of the Delphi RTL as possible for size reasons.
Considering the situation with false positives, inflating the files is maybe desirable. A week or so ago I tried uploading a ZGE project to a Discord group and it got blocked immediately.

Re: getSystemTime() gives different results on different devices

Posted: Sat May 01, 2021 7:31 pm
by Ats
As long as Windows returns a timestamp instead of an amount of seconds since midnight :D

But how is this inflating the exe? SysUtils is already used. Is DateUtils heavy?

Re: getSystemTime() gives different results on different devices

Posted: Mon May 03, 2021 7:40 am
by VilleK
SysUtils is not used in "minimal" build. If you check the sources there are "$ifndef minimal" blocks around every use.

One of the initial design goals of ZGameEditor was to have a super-tiny runtime and I will try to maintain that even if we currently have to inflate the binaries a bit to avoid over-sensitive virus scanners :)

There should be a Windows-function we can call on windows to get the same precision.

Re: getSystemTime() gives different results on different devices

Posted: Mon May 03, 2021 10:14 am
by Kjell
Hi guys,
VilleK wrote: Mon May 03, 2021 7:40 amThere should be a Windows-function we can call on windows to get the same precision.
Windows has GetSystemTimeAsFileTime which gives you the number of 100-nanosecond intervals since January 1, 1601 (UTC) and can be converted to Unix time pretty easily.

+ Do keep in mind that a 32-bit Unix timestamp will roll-over on the 7th of February in 2106, so your games might not work properly after that :wink:

++ In fact, a 32-bit Unix timestamp will enter unsigned territory on the 19th of January in 2038, so you'll need to do some masking & shifting to prevent the value from being incorrect in ZGE after that ( due to the lack of unsigned integers ).

K