From 0a2e59c243ac2b6cb5e053cc892fd712f26ee573 Mon Sep 17 00:00:00 2001 From: ondrej Date: Tue, 3 Nov 2020 11:41:28 +0000 Subject: [PATCH] GetLocalTimeOffset: DateTime-aware overloads for Unix. Issue #35710 git-svn-id: trunk@47290 - (cherry picked from commit 282aa0daa7f469eed11978569842255b0c46e1d5) --- rtl/unix/sysutils.pp | 20 +++++++++++++++- rtl/unix/timezone.inc | 55 ++++++++++++++++++++++++++----------------- rtl/unix/unix.pp | 35 ++++++++++++++++++++------- rtl/unix/unixutil.pp | 29 ++++++++++++++++++++++- 4 files changed, 106 insertions(+), 33 deletions(-) diff --git a/rtl/unix/sysutils.pp b/rtl/unix/sysutils.pp index 8c596f52a0..52ee2e019c 100644 --- a/rtl/unix/sysutils.pp +++ b/rtl/unix/sysutils.pp @@ -1671,8 +1671,26 @@ end; function GetLocalTimeOffset(const DateTime: TDateTime; out Offset: Integer): Boolean; +var + Year, Month, Day, Hour, Minute, Second, MilliSecond: word; + UnixTime: Int64; + lc,lh: cint; + lTZInfo: TTZInfo; begin - Result := False; // ToDo + DecodeDate(DateTime, Year, Month, Day); + DecodeTime(DateTime, Hour, Minute, Second, MilliSecond); + UnixTime:=LocalToEpoch(Year, Month, Day, Hour, Minute, Second); + { check if time is in current global Tzinfo } + if (Tzinfo.validsinceleaps[i].transition); - leap_correct:=leaps[i].change; + ATZInfo.leap_correct:=leaps[i].change; if (timer=leaps[i].transition) and (((i=0) and (leaps[i].change>0)) or (leaps[i].change>leaps[i-1].change)) then begin - leap_hit:=1; + ATZInfo.leap_hit:=1; while (i>0) and (leaps[i].transition=leaps[i-1].transition+1) and (leaps[i].change=leaps[i-1].change+1) do begin - inc(leap_hit); + inc(ATZInfo.leap_hit); dec(i); end; end; end; -procedure GetLocalTimezone(timer:longint); -var - lc,lh : longint; +procedure GetLocalTimezone(timer:cint); begin - GetLocalTimezone(timer,lc,lh); + GetLocalTimezone(timer,Tzinfo,true); end; Const @@ -339,6 +349,7 @@ end; procedure InitLocalTime; begin + ReloadTzinfo:=@InitLocalTime; ReadTimezoneFile(GetTimezoneFile); GetLocalTimezone(fptime); end; diff --git a/rtl/unix/unix.pp b/rtl/unix/unix.pp index f41b1a1b18..00c741d0e1 100644 --- a/rtl/unix/unix.pp +++ b/rtl/unix/unix.pp @@ -16,7 +16,9 @@ Unit Unix; Interface Uses - BaseUnix,UnixType; + BaseUnix,UnixType, + UnixUtil // tzseconds + ; // If you deprecated new symbols, please annotate the version. // this makes it easier to decide if they can already be removed. @@ -52,9 +54,10 @@ Const {** Time/Date Handling **} -var - tzdaylight : boolean; - tzname : array[boolean] of pchar; + function Gettzdaylight : boolean; + function Gettzname(const b : boolean) : pchar; + property tzdaylight : boolean read Gettzdaylight; + property tzname[b : boolean] : pchar read Gettzname; {************ Procedure/Functions ************} @@ -66,7 +69,7 @@ var // it doesn't (yet) work for. { timezone support } -procedure GetLocalTimezone(timer:cint;var leap_correct,leap_hit:cint); +function GetLocalTimezone(timer:cint;var ATZInfo:TTZInfo;FullInfo:Boolean):Boolean; procedure GetLocalTimezone(timer:cint); procedure ReadTimezoneFile(fn:string); function GetTimezoneFile:string; @@ -141,10 +144,10 @@ Function FSearch (const path:UnicodeString;dirlist:UnicodeString):UnicodeStrin Implementation -Uses - UnixUtil // tzseconds - {$ifndef FPC_USE_LIBC},Syscall{$endif} - ; +{$ifndef FPC_USE_LIBC} +Uses + Syscall; +{$endif} {$i unxovl.inc} @@ -157,6 +160,20 @@ Uses Function getenv(name:string):Pchar; external name 'FPC_SYSC_FPGETENV'; +{****************************************************************************** + timezone support +******************************************************************************} + +function Gettzdaylight : boolean; +begin + Gettzdaylight:=Tzinfo.daylight; +end; + +function Gettzname(const b : boolean) : pchar; +begin + Gettzname:=Tzinfo.name[b]; +end; + {****************************************************************************** Process related calls ******************************************************************************} diff --git a/rtl/unix/unixutil.pp b/rtl/unix/unixutil.pp index dc3447306d..43ddc36100 100644 --- a/rtl/unix/unixutil.pp +++ b/rtl/unix/unixutil.pp @@ -27,8 +27,25 @@ unit unixutil; interface +uses BaseUnix; + +type + TTZInfo = record + daylight : boolean; + name : array[boolean] of pchar; + seconds : Longint; // difference from UTC + validsince : int64; // UTC timestamp + validuntil : int64; // UTC timestamp + leap_correct : longint; + leap_hit : longint; + end; + var - Tzseconds : Longint; + Tzinfo : TTZInfo; + ReloadTzinfo : TProcedure; + +Function GetTzseconds : Longint; +property Tzseconds : Longint read GetTzseconds; Function StringToPPChar(S: PChar;ReserveEntries:integer):ppchar; Function StringToPPChar(Var S:RawByteString;ReserveEntries:integer):ppchar; @@ -40,6 +57,16 @@ Function GregorianToJulian(Year,Month,Day:Longint):LongInt; deprecated 'use Date implementation +Function GetTzseconds : Longint; +var + curtime: time_t; +begin + curtime:=fptime; + if assigned(ReloadTzinfo) and ((curtimeTzinfo.validuntil+Tzinfo.seconds)) then + ReloadTzinfo; + GetTzseconds:=Tzinfo.seconds; +end; + function ArrayStringToPPchar(const S:Array of RawByteString;reserveentries:Longint):ppchar; // const ? // Extra allocate reserveentries pchar's at the beginning (default param=0 after 1.0.x ?) // Note: for internal use by skilled programmers only