#1 2021-09-10 21:42:51

macfly
Member
From: Brasil
Registered: 2016-08-20
Posts: 374

Datetime to UnixtimeUTC

Probably a silly question, but is there any way to convert a TDateTime to UnixtimeUTC without using TSynZone?

Offline

#2 2021-09-11 08:07:57

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: Datetime to UnixtimeUTC

TSynTimeZone is indeed a cross-platform way of converting local time to/from UTC.
You could safely call TSynTimeZone.Default.LocalToUtc() for this conversion.

Under Delphi XE+, you have http://docwiki.embarcadero.com/Librarie … .TTimeZone which is slower, and only works with the current local zone - it is not usable for several time zones.
On FPC, you only get the CURRENT time bias, so it is good for the current date/time only: it would be inaccurate for past/future dates.

Edit: on mORMot 2, I have just made TSynTimeZone thread-safe and included some global wrapper functions for local time processing.
Check https://github.com/synopse/mORMot2/comm … b704600c28

Offline

#3 2021-09-11 13:43:49

macfly
Member
From: Brasil
Registered: 2016-08-20
Posts: 374

Re: Datetime to UnixtimeUTC

Thank you for the detailed explanations.

The server needs to get the date from a file with FileAgeToDateTime and pass it to the client in UnixTimeUTC.

As a temporary solution I used UnixTime - UnixTimeUTC to find the difference in hours and make the adjustment.
It works in this specific case but obviously there must be situations where this fails.

I was trying to avoid TSynTimeZone so I wouldn't have to deal with extracting data from the Windows registry to use on Linux.
But I'm going to use it to do it right.

Making TSynTimeZone thread safe helps a lot.

Thank you for the changes.

Offline

#4 2021-09-11 20:22:02

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: Datetime to UnixtimeUTC

Perhaps I will include updated TSynTimeZone .res and .tz files as part of the repository, generated from a Windows 10 up-to-date system, ready to be included on Linux.
So you could just include a {$R ....} in your code and you have everything up-to-date and embedded within the Linux/POSIX executable.

It may help using this component. My guess is that this .res would be much smaller than regular tzdata, and that it would need an upgrade only every few months.

Offline

#5 2021-09-12 01:24:15

macfly
Member
From: Brasil
Registered: 2016-08-20
Posts: 374

Re: Datetime to UnixtimeUTC

Thanks ab, working fine with these updates.

As it is information extracted from Windows, I don't know if there may be any problem in making this file available in the repository.

Maybe it's better that each one does the extraction.

LoadFromRegistry/SaveToFile simplify a lot.

Offline

#6 2021-09-12 14:21:08

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: Datetime to UnixtimeUTC

I have included a new mormot.tz.res file, ready to be included on POSIX/Linux.

Anyone is free to make its own extraction, but here is something at hand, which would be updated together with the main mORMot repository from time to time, so could be used as reference.

Offline

#7 2021-09-13 18:56:51

macfly
Member
From: Brasil
Registered: 2016-08-20
Posts: 374

Re: Datetime to UnixtimeUTC

On Linux only, I'm getting "EFastReader: Reached End of Input" when trying to load timezones, either using file or resource.

On Windows it works OK, even loading from very same file.

Offline

#8 2021-09-13 19:24:14

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: Datetime to UnixtimeUTC

On which processor on which Linux?
Which FPC compiler are you using?

I don't have any problem to run the latest regression tests with 32-bit or 64-bit Linux, which read the new resource file.
Not only on i386 and x86_64, but also on Aarch64...

Do the latest regression tests pass on your side?
TTestCoreBase.TimeZones from test.core.base.pas tries to validate our supplied resource file.

Offline

#9 2021-09-13 20:27:30

macfly
Member
From: Brasil
Registered: 2016-08-20
Posts: 374

Re: Datetime to UnixtimeUTC

Hi ab,

Lazarus 2.0.10 + FPC 3.2.0 Win 32 Cross compiling to Linux x64.
Ubuntu 20.04.2 LTS (GNU/Linux 5.11.0-1016-oracle x86_64)

This is an instance in oracle's "Always Free", but running on x86_64 / not ampere Aarch64.

Sample project:
https://github.com/devaex/TestTimeZone

My findings:
Creating an instance works.

But when calling the TSynTimeZone.Default instance, the error occurs.

Yes tests pass, but from what I saw, TTestCoreBase.TimeZones don't test using TSynTimeZone.Default, on linux.

  writeln(TSynTimeZone.Default.NowToLocal('UTC'));   <-- error here  

Last edited by macfly (2021-09-13 20:27:58)

Offline

#10 2021-09-13 23:24:08

macfly
Member
From: Brasil
Registered: 2016-08-20
Posts: 374

Re: Datetime to UnixtimeUTC

Edit: The problem seems to be in LoadFromFile when the file doesn't exist.

It also occurs on Windows and even creating the instance.


I believe that in TSynTimeZone.LoadFromFile the existence of the file must be checked, because if an empty string is passed, as CreateDefault does, it tries to load a file that might not exist.
And pass a empty string to LoadFromBuffer.

procedure TSynTimeZone.LoadFromFile(const FileName: TFileName);
var
  FN: TFileName;
begin
  if FileName = '' then
    FN := ChangeFileExt(Executable.ProgramFileName, '.tz')
  else
    FN := FileName;
  LoadFromBuffer(StringFromFile(FN)); <--  if FileName are empty or invalid pass a empty string to LoadFromBuffer
end; 

Last edited by macfly (2021-09-13 23:26:51)

Offline

#11 2021-09-14 08:17:09

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: Datetime to UnixtimeUTC

You are right.

Should be fixed now.

Offline

Board footer

Powered by FluxBB