mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-21 20:29:32 +02:00
GetLocalTimeOffset: DateTime-aware overloads for Unix. Issue #35710
git-svn-id: trunk@47290 -
(cherry picked from commit 282aa0daa7
)
This commit is contained in:
parent
e62556e7f1
commit
0a2e59c243
@ -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.validsince<UnixTime) and (UnixTime<Tzinfo.validuntil) then
|
||||
begin
|
||||
Result:=True;
|
||||
Offset:=-TZInfo.seconds div 60;
|
||||
end else
|
||||
begin
|
||||
Result:=GetLocalTimezone(UnixTime,lTZInfo,False);
|
||||
if Result then
|
||||
Offset:=-lTZInfo.seconds div 60;
|
||||
end;
|
||||
end;
|
||||
|
||||
{$ifdef android}
|
||||
|
@ -41,7 +41,7 @@ var
|
||||
zone_names : pchar = Nil;
|
||||
leaps : pleap = Nil;
|
||||
|
||||
function find_transition(timer:longint):pttinfo;
|
||||
function find_transition(timer:longint;var trans_start,trans_end:longint):pttinfo;
|
||||
var
|
||||
i : longint;
|
||||
begin
|
||||
@ -52,6 +52,9 @@ begin
|
||||
inc(i);
|
||||
if (i=num_types) then
|
||||
i:=0;
|
||||
{ unknown transition boundaries }
|
||||
trans_start:=low(trans_start);
|
||||
trans_end:=high(trans_end);
|
||||
end
|
||||
else
|
||||
begin
|
||||
@ -62,65 +65,72 @@ begin
|
||||
break;
|
||||
inc(i);
|
||||
end;
|
||||
trans_start:=transitions[i-1];
|
||||
trans_end:=transitions[i];
|
||||
i:=type_idxs[i-1];
|
||||
end;
|
||||
find_transition:=@types[i];
|
||||
end;
|
||||
|
||||
|
||||
procedure GetLocalTimezone(timer:longint;var leap_correct,leap_hit:longint);
|
||||
function GetLocalTimezone(timer:cint;var ATZInfo:TTZInfo;FullInfo:Boolean):Boolean;
|
||||
var
|
||||
info : pttinfo;
|
||||
i : longint;
|
||||
i,trans_start,trans_end : longint;
|
||||
begin
|
||||
{ reset }
|
||||
TZDaylight:=false;
|
||||
TZSeconds:=0;
|
||||
TZName[false]:=nil;
|
||||
TZName[true]:=nil;
|
||||
leap_correct:=0;
|
||||
leap_hit:=0;
|
||||
ATZInfo.Daylight:=false;
|
||||
ATZInfo.Seconds:=0;
|
||||
ATZInfo.Name[false]:=nil;
|
||||
ATZInfo.Name[true]:=nil;
|
||||
ATZInfo.validsince:=0;
|
||||
ATZInfo.validuntil:=0;
|
||||
ATZInfo.leap_correct:=0;
|
||||
ATZInfo.leap_hit:=0;
|
||||
{ get info }
|
||||
info:=find_transition(timer);
|
||||
if not assigned(info) then
|
||||
info:=find_transition(timer,trans_start,trans_end);
|
||||
GetLocalTimezone:=assigned(info);
|
||||
if not GetLocalTimezone then
|
||||
exit;
|
||||
TZDaylight:=info^.isdst;
|
||||
TZSeconds:=info^.offset;
|
||||
ATZInfo.validsince:=trans_start;
|
||||
ATZInfo.validuntil:=trans_end;
|
||||
ATZInfo.Daylight:=info^.isdst;
|
||||
ATZInfo.Seconds:=info^.offset;
|
||||
if not FullInfo then
|
||||
Exit;
|
||||
i:=0;
|
||||
while (i<num_types) do
|
||||
begin
|
||||
tzname[types[i].isdst]:=@zone_names[types[i].idx];
|
||||
ATZInfo.name[types[i].isdst]:=@zone_names[types[i].idx];
|
||||
inc(i);
|
||||
end;
|
||||
tzname[info^.isdst]:=@zone_names[info^.idx];
|
||||
ATZInfo.name[info^.isdst]:=@zone_names[info^.idx];
|
||||
i:=num_leaps;
|
||||
repeat
|
||||
if i=0 then
|
||||
exit;
|
||||
dec(i);
|
||||
until (timer>leaps[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;
|
||||
|
@ -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
|
||||
******************************************************************************}
|
||||
|
@ -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 ((curtime<Tzinfo.validsince+Tzinfo.seconds) or (curtime>Tzinfo.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
|
||||
|
Loading…
Reference in New Issue
Block a user