getSystemTime() gives different results on different devices

Found a bug? Post information about it here so we can fix it!

Moderator: Moderators

Post Reply
User avatar
Ats
Posts: 711
Joined: Fri Sep 28, 2012 10:05 am
Contact:

getSystemTime() gives different results on different devices

Post 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.
User avatar
VilleK
Site Admin
Posts: 2320
Joined: Mon Jan 15, 2007 4:50 pm
Location: Stockholm, Sweden
Contact:

Re: getSystemTime() gives different results on different devices

Post 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.
User avatar
Ats
Posts: 711
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: getSystemTime() gives different results on different devices

Post 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
User avatar
Ats
Posts: 711
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: getSystemTime() gives different results on different devices

Post 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;
User avatar
Ats
Posts: 711
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: getSystemTime() gives different results on different devices

Post 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
User avatar
Ats
Posts: 711
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: getSystemTime() gives different results on different devices

Post 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;
User avatar
Ats
Posts: 711
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: getSystemTime() gives different results on different devices

Post 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...
User avatar
Ats
Posts: 711
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: getSystemTime() gives different results on different devices

Post 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?
User avatar
VilleK
Site Admin
Posts: 2320
Joined: Mon Jan 15, 2007 4:50 pm
Location: Stockholm, Sweden
Contact:

Re: getSystemTime() gives different results on different devices

Post 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.
User avatar
rrTea
Posts: 475
Joined: Sat Feb 15, 2014 9:54 am

Re: getSystemTime() gives different results on different devices

Post 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.
User avatar
Ats
Posts: 711
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: getSystemTime() gives different results on different devices

Post 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?
User avatar
VilleK
Site Admin
Posts: 2320
Joined: Mon Jan 15, 2007 4:50 pm
Location: Stockholm, Sweden
Contact:

Re: getSystemTime() gives different results on different devices

Post 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.
User avatar
Kjell
Posts: 1910
Joined: Sat Feb 23, 2008 11:15 pm

Re: getSystemTime() gives different results on different devices

Post 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
Post Reply