mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-19 10:09:19 +02:00
+ timezone support
This commit is contained in:
parent
368452de05
commit
ed5e78cc36
@ -478,16 +478,24 @@ Function SysCall(callnr:longint;var regs:SysCallregs):longint;
|
|||||||
Time/Date Handling
|
Time/Date Handling
|
||||||
***************************}
|
***************************}
|
||||||
|
|
||||||
Function GetEpochTime:longint;
|
var
|
||||||
Procedure GetTimeOfDay(var tv:timeval;var tz:timezone);
|
tzdaylight : boolean;
|
||||||
Procedure SetTimeOfDay(Const tv:timeval;const tz:timezone);
|
tzseconds : longint;
|
||||||
Function GetTimeOfDay: longint;
|
tzname : array[boolean] of pchar;
|
||||||
|
|
||||||
|
{ timezone support }
|
||||||
|
procedure GetLocalTimezone(timer:longint;var leap_correct,leap_hit:longint);
|
||||||
|
procedure GetLocalTimezone(timer:longint);
|
||||||
|
procedure ReadTimezoneFile(fn:string);
|
||||||
|
function GetTimezoneFile:string;
|
||||||
|
|
||||||
|
Procedure GetTimeOfDay(var tv:timeval);
|
||||||
|
Function GetTimeOfDay:longint;
|
||||||
Procedure EpochToLocal(epoch:longint;var year,month,day,hour,minute,second:Word);
|
Procedure EpochToLocal(epoch:longint;var year,month,day,hour,minute,second:Word);
|
||||||
Function LocalToEpoch(year,month,day,hour,minute,second:Word):Longint;
|
Function LocalToEpoch(year,month,day,hour,minute,second:Word):Longint;
|
||||||
Procedure GetTime(Var Hour,Minute,Second:Word);
|
Procedure GetTime(Var Hour,Minute,Second:Word);
|
||||||
Procedure GetDate(Var Year,Month,Day:Word);
|
Procedure GetDate(Var Year,Month,Day:Word);
|
||||||
Procedure GetTime(Var Hour,Minute,Second:Integer);
|
Procedure GetDateTime(Var Year,Month,Day,hour,minute,second:Word);
|
||||||
Procedure GetDate(Var Year,Month,Day:Integer);
|
|
||||||
|
|
||||||
{**************************
|
{**************************
|
||||||
Process Handling
|
Process Handling
|
||||||
@ -735,9 +743,6 @@ Implementation
|
|||||||
|
|
||||||
Uses Strings;
|
Uses Strings;
|
||||||
|
|
||||||
var
|
|
||||||
LocalTZ:TimeZone;
|
|
||||||
|
|
||||||
|
|
||||||
{ Get the definitions of textrec and filerec }
|
{ Get the definitions of textrec and filerec }
|
||||||
{$i textrec.inc}
|
{$i textrec.inc}
|
||||||
@ -1275,32 +1280,20 @@ end;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
Procedure GetTimeOfDay(var tv:timeval;var tz:timezone);
|
Procedure GetTimeOfDay(var tv:timeval);
|
||||||
{
|
{
|
||||||
Get the time of day and timezone.
|
Get the number of seconds since 00:00, January 1 1970, GMT
|
||||||
|
the time NOT corrected any way
|
||||||
}
|
}
|
||||||
var
|
var
|
||||||
regs : SysCallregs;
|
regs : SysCallregs;
|
||||||
begin
|
begin
|
||||||
regs.reg2:=longint(@tv);
|
regs.reg2:=longint(@tv);
|
||||||
regs.reg3:=longint(@tz);
|
regs.reg3:=0;
|
||||||
SysCall(SysCall_nr_gettimeofday,regs);
|
SysCall(SysCall_nr_gettimeofday,regs);
|
||||||
LinuxError:=Errno;
|
LinuxError:=Errno;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Procedure SetTimeOfDay(Const tv:timeval;Const tz:timezone);
|
|
||||||
{
|
|
||||||
Get the time of day and timezone.
|
|
||||||
}
|
|
||||||
var
|
|
||||||
regs : SysCallregs;
|
|
||||||
begin
|
|
||||||
regs.reg2:=longint(@tv);
|
|
||||||
regs.reg3:=longint(@tz);
|
|
||||||
SysCall(SysCall_nr_settimeofday,regs);
|
|
||||||
LinuxError:=Errno;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
Function GetTimeOfDay: longint;
|
Function GetTimeOfDay: longint;
|
||||||
{
|
{
|
||||||
@ -1308,47 +1301,25 @@ Function GetTimeOfDay: longint;
|
|||||||
the time NOT corrected any way
|
the time NOT corrected any way
|
||||||
}
|
}
|
||||||
var
|
var
|
||||||
t : timeval ;
|
regs : SysCallregs;
|
||||||
tz : timezone ;
|
tv : timeval;
|
||||||
begin
|
begin
|
||||||
gettimeofday(t,tz);{Sets LinuxError also}
|
regs.reg2:=longint(@tv);
|
||||||
GetTimeOfDay:=t.sec;
|
regs.reg3:=0;
|
||||||
end;
|
SysCall(SysCall_nr_gettimeofday,regs);
|
||||||
|
LinuxError:=Errno;
|
||||||
|
GetTimeOfDay:=tv.sec;
|
||||||
Function GetEpochTime:longint;
|
|
||||||
{
|
|
||||||
Get the number of seconds since 00:00, January 1 1970, GMT
|
|
||||||
the time is corrected according to the time zone, but NOT
|
|
||||||
DST corrected.
|
|
||||||
}
|
|
||||||
var
|
|
||||||
t : timeval ;
|
|
||||||
tz : timezone ;
|
|
||||||
begin
|
|
||||||
gettimeofday(t,tz);{Sets LinuxError also}
|
|
||||||
Getepochtime:=t.sec-tz.minuteswest*60;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Procedure InitEpochToLocal;
|
|
||||||
var
|
|
||||||
tv:TimeVal;
|
|
||||||
begin
|
|
||||||
GetTimeOfDay(tv,LocalTZ);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
Procedure EpochToLocal(epoch:longint;var year,month,day,hour,minute,second:Word);
|
Procedure EpochToLocal(epoch:longint;var year,month,day,hour,minute,second:Word);
|
||||||
{
|
{
|
||||||
Transforms Epoch time(seconds since 00:00, january 1 1970, corrected for
|
Transforms Epoch time into local time (hour, minute,seconds)
|
||||||
local time zone) into local time (hour, minute,seconds)
|
|
||||||
}
|
}
|
||||||
Var
|
Var
|
||||||
DateNum: LongInt;
|
DateNum: LongInt;
|
||||||
Begin { Beginning of Localtime }
|
Begin
|
||||||
// dec(Epoch,LocalTZ.minuteswest*60);
|
inc(Epoch,TZSeconds);
|
||||||
Datenum:=(Epoch Div 86400) + c1970;
|
Datenum:=(Epoch Div 86400) + c1970;
|
||||||
JulianToGregorian(DateNum,Year,Month,day);
|
JulianToGregorian(DateNum,Year,Month,day);
|
||||||
Epoch:=Epoch Mod 86400;
|
Epoch:=Epoch Mod 86400;
|
||||||
@ -1366,14 +1337,13 @@ Function LocalToEpoch(year,month,day,hour,minute,second:Word):Longint;
|
|||||||
}
|
}
|
||||||
Begin
|
Begin
|
||||||
LocalToEpoch:=((GregorianToJulian(Year,Month,Day)-c1970)*86400)+
|
LocalToEpoch:=((GregorianToJulian(Year,Month,Day)-c1970)*86400)+
|
||||||
(LongInt(Hour)*3600)+(Minute*60)+Second+(LocalTZ.minuteswest*60);
|
(LongInt(Hour)*3600)+(Minute*60)+Second-TZSeconds;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
|
||||||
Procedure GetTime(Var Hour,Minute,Second:Word);
|
Procedure GetTime(Var Hour,Minute,Second:Word);
|
||||||
{
|
{
|
||||||
Gets the current time, adjusted to local time, but not DST,
|
Gets the current time, adjusted to local time
|
||||||
in hours, minutes and seconds.
|
|
||||||
}
|
}
|
||||||
var
|
var
|
||||||
year,day,month:Word;
|
year,day,month:Word;
|
||||||
@ -1385,8 +1355,7 @@ End;
|
|||||||
|
|
||||||
Procedure GetDate(Var Year,Month,Day:Word);
|
Procedure GetDate(Var Year,Month,Day:Word);
|
||||||
{
|
{
|
||||||
Gets the current date, adjusted to local time, but not DST,
|
Gets the current date, adjusted to local time
|
||||||
in year,month,day.
|
|
||||||
}
|
}
|
||||||
var
|
var
|
||||||
hour,minute,second : Word;
|
hour,minute,second : Word;
|
||||||
@ -1395,16 +1364,16 @@ Begin
|
|||||||
End;
|
End;
|
||||||
|
|
||||||
|
|
||||||
Procedure GetTime(Var Hour,Minute,Second:Integer);
|
Procedure GetDateTime(Var Year,Month,Day,hour,minute,second:Word);
|
||||||
begin
|
{
|
||||||
GetTime(Word(Hour),Word(Minute),Word(Second));
|
Gets the current date, adjusted to local time
|
||||||
end;
|
}
|
||||||
|
Begin
|
||||||
|
EpochToLocal(GetTimeOfDay,year,month,day,hour,minute,second);
|
||||||
|
End;
|
||||||
|
|
||||||
|
{ Include timezone handling routines which use /usr/share/timezone info }
|
||||||
Procedure GetDate(Var Year,Month,Day:Integer);
|
{$i timezone.inc}
|
||||||
begin
|
|
||||||
GetDate(Word(Year),Word(Month),Word(Day));
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
{******************************************************************************
|
{******************************************************************************
|
||||||
@ -3808,13 +3777,20 @@ end;
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
|
|
||||||
Begin
|
Initialization
|
||||||
InitEpochToLocal;
|
InitLocalTime;
|
||||||
|
|
||||||
|
finalization
|
||||||
|
DoneLocalTime;
|
||||||
|
|
||||||
End.
|
End.
|
||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.53 1999-11-14 21:35:04 peter
|
Revision 1.54 1999-12-01 22:46:59 peter
|
||||||
|
+ timezone support
|
||||||
|
|
||||||
|
Revision 1.53 1999/11/14 21:35:04 peter
|
||||||
* removed warnings
|
* removed warnings
|
||||||
|
|
||||||
Revision 1.52 1999/11/14 11:11:15 michael
|
Revision 1.52 1999/11/14 11:11:15 michael
|
||||||
|
261
rtl/linux/timezone.inc
Normal file
261
rtl/linux/timezone.inc
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
{
|
||||||
|
$Id$
|
||||||
|
|
||||||
|
Support for timezone info in /usr/share/timezone
|
||||||
|
}
|
||||||
|
|
||||||
|
type
|
||||||
|
plongint=^longint;
|
||||||
|
pbyte=^byte;
|
||||||
|
|
||||||
|
ttzhead=packed record
|
||||||
|
tzh_reserved : array[0..19] of byte;
|
||||||
|
tzh_ttisgmtcnt,
|
||||||
|
tzh_ttisstdcnt,
|
||||||
|
tzh_leapcnt,
|
||||||
|
tzh_timecnt,
|
||||||
|
tzh_typecnt,
|
||||||
|
tzh_charcnt : longint;
|
||||||
|
end;
|
||||||
|
|
||||||
|
pttinfo=^tttinfo;
|
||||||
|
tttinfo=packed record
|
||||||
|
offset : longint;
|
||||||
|
isdst : boolean;
|
||||||
|
idx : byte;
|
||||||
|
isstd : byte;
|
||||||
|
isgmt : byte;
|
||||||
|
end;
|
||||||
|
|
||||||
|
pleap=^tleap;
|
||||||
|
tleap=record
|
||||||
|
transition : longint;
|
||||||
|
change : longint;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
num_transitions,
|
||||||
|
num_leaps,
|
||||||
|
num_types : longint;
|
||||||
|
|
||||||
|
transitions : plongint;
|
||||||
|
type_idxs : pbyte;
|
||||||
|
types : pttinfo;
|
||||||
|
zone_names : pchar;
|
||||||
|
leaps : pleap;
|
||||||
|
|
||||||
|
function find_transition(timer:longint):pttinfo;
|
||||||
|
var
|
||||||
|
i : longint;
|
||||||
|
begin
|
||||||
|
if (num_transitions=0) or (timer<transitions[0]) then
|
||||||
|
begin
|
||||||
|
i:=0;
|
||||||
|
while (i<num_types) and (types[i].isdst) do
|
||||||
|
inc(i);
|
||||||
|
if (i=num_types) then
|
||||||
|
i:=0;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
for i:=1 to num_transitions do
|
||||||
|
if (timer<transitions[i]) then
|
||||||
|
break;
|
||||||
|
i:=type_idxs[i-1];
|
||||||
|
end;
|
||||||
|
find_transition:=@types[i];
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure GetLocalTimezone(timer:longint;var leap_correct,leap_hit:longint);
|
||||||
|
var
|
||||||
|
info : pttinfo;
|
||||||
|
i : longint;
|
||||||
|
begin
|
||||||
|
info:=find_transition(timer);
|
||||||
|
TZDaylight:=info^.isdst;
|
||||||
|
TZSeconds:=info^.offset;
|
||||||
|
i:=0;
|
||||||
|
while (i<num_types) and (i<2) do
|
||||||
|
begin
|
||||||
|
tzname[types[i].isdst]:=@zone_names[types[i].idx];
|
||||||
|
inc(i);
|
||||||
|
end;
|
||||||
|
tzname[info^.isdst]:=@zone_names[info^.idx];
|
||||||
|
leap_correct:=0;
|
||||||
|
leap_hit:=0;
|
||||||
|
i:=num_leaps;
|
||||||
|
while (i>0) do
|
||||||
|
begin
|
||||||
|
if (timer>leaps[i].transition) then
|
||||||
|
break;
|
||||||
|
dec(i);
|
||||||
|
end;
|
||||||
|
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;
|
||||||
|
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);
|
||||||
|
dec(i);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure GetLocalTimezone(timer:longint);
|
||||||
|
var
|
||||||
|
lc,lh : longint;
|
||||||
|
begin
|
||||||
|
GetLocalTimezone(timer,lc,lh);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure ReadTimezoneFile(fn:string);
|
||||||
|
|
||||||
|
procedure decode(var l:longint);
|
||||||
|
var
|
||||||
|
k : longint;
|
||||||
|
p : pbyte;
|
||||||
|
begin
|
||||||
|
p:=pbyte(@l);
|
||||||
|
if (p[0] and (1 shl 7))<>0 then
|
||||||
|
k:=not 0
|
||||||
|
else
|
||||||
|
k:=0;
|
||||||
|
k:=(k shl 8) or p[0];
|
||||||
|
k:=(k shl 8) or p[1];
|
||||||
|
k:=(k shl 8) or p[2];
|
||||||
|
k:=(k shl 8) or p[3];
|
||||||
|
l:=k;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
f : longint;
|
||||||
|
tzdir : string;
|
||||||
|
tzhead : ttzhead;
|
||||||
|
i : longint;
|
||||||
|
chars : longint;
|
||||||
|
buf : pbyte;
|
||||||
|
begin
|
||||||
|
if fn='' then
|
||||||
|
fn:='localtime';
|
||||||
|
if fn[1]<>'/' then
|
||||||
|
begin
|
||||||
|
tzdir:=getenv('TZDIR');
|
||||||
|
if tzdir='' then
|
||||||
|
tzdir:='/usr/share/zoneinfo';
|
||||||
|
if tzdir[length(tzdir)]<>'/' then
|
||||||
|
tzdir:=tzdir+'/';
|
||||||
|
fn:=tzdir+fn;
|
||||||
|
end;
|
||||||
|
f:=fdopen(fn,Open_RdOnly);
|
||||||
|
if f<0 then
|
||||||
|
exit;
|
||||||
|
i:=fdread(f,tzhead,sizeof(tzhead));
|
||||||
|
if i<>sizeof(tzhead) then
|
||||||
|
exit;
|
||||||
|
decode(tzhead.tzh_timecnt);
|
||||||
|
decode(tzhead.tzh_typecnt);
|
||||||
|
decode(tzhead.tzh_charcnt);
|
||||||
|
decode(tzhead.tzh_leapcnt);
|
||||||
|
decode(tzhead.tzh_ttisstdcnt);
|
||||||
|
decode(tzhead.tzh_ttisgmtcnt);
|
||||||
|
|
||||||
|
num_transitions:=tzhead.tzh_timecnt;
|
||||||
|
num_types:=tzhead.tzh_typecnt;
|
||||||
|
chars:=tzhead.tzh_charcnt;
|
||||||
|
|
||||||
|
reallocmem(transitions,num_transitions*sizeof(longint));
|
||||||
|
reallocmem(type_idxs,num_transitions);
|
||||||
|
reallocmem(types,num_types*sizeof(tttinfo));
|
||||||
|
reallocmem(zone_names,chars);
|
||||||
|
reallocmem(leaps,num_leaps*sizeof(tleap));
|
||||||
|
|
||||||
|
fdread(f,transitions^,num_transitions*4);
|
||||||
|
fdread(f,type_idxs^,num_transitions);
|
||||||
|
|
||||||
|
for i:=0 to num_transitions-1 do
|
||||||
|
decode(transitions[i]);
|
||||||
|
|
||||||
|
for i:=0 to num_types-1 do
|
||||||
|
begin
|
||||||
|
fdread(f,types[i].offset,4);
|
||||||
|
fdread(f,types[i].isdst,1);
|
||||||
|
fdread(f,types[i].idx,1);
|
||||||
|
decode(types[i].offset);
|
||||||
|
types[i].isstd:=0;
|
||||||
|
types[i].isgmt:=0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
fdread(f,zone_names^,chars);
|
||||||
|
|
||||||
|
for i:=0 to num_leaps-1 do
|
||||||
|
begin
|
||||||
|
fdread(f,leaps[i].transition,4);
|
||||||
|
fdread(f,leaps[i].change,4);
|
||||||
|
decode(leaps[i].transition);
|
||||||
|
decode(leaps[i].change);
|
||||||
|
end;
|
||||||
|
|
||||||
|
getmem(buf,tzhead.tzh_ttisstdcnt);
|
||||||
|
fdread(f,buf^,tzhead.tzh_ttisstdcnt);
|
||||||
|
for i:=0 to tzhead.tzh_ttisstdcnt-1 do
|
||||||
|
types[i].isstd:=byte(buf[i]<>0);
|
||||||
|
freemem(buf);
|
||||||
|
|
||||||
|
getmem(buf,tzhead.tzh_ttisgmtcnt);
|
||||||
|
fdread(f,buf^,tzhead.tzh_ttisgmtcnt);
|
||||||
|
for i:=0 to tzhead.tzh_ttisgmtcnt-1 do
|
||||||
|
types[i].isgmt:=byte(buf[i]<>0);
|
||||||
|
freemem(buf);
|
||||||
|
fdclose(f);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function GetTimezoneFile:string;
|
||||||
|
var
|
||||||
|
f,len : longint;
|
||||||
|
s : string;
|
||||||
|
begin
|
||||||
|
GetTimezoneFile:='';
|
||||||
|
f:=fdopen('/etc/timezone',Open_RdOnly);
|
||||||
|
if f=0 then
|
||||||
|
exit;
|
||||||
|
len:=fdread(f,s[1],high(s));
|
||||||
|
s[0]:=chr(len);
|
||||||
|
len:=pos(#10,s);
|
||||||
|
if len<>0 then
|
||||||
|
s[0]:=chr(len-1);
|
||||||
|
fdclose(f);
|
||||||
|
GetTimezoneFile:=s;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure InitLocalTime;
|
||||||
|
begin
|
||||||
|
ReadTimezoneFile(GetTimezoneFile);
|
||||||
|
GetLocalTimezone(GetTimeOfDay);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure DoneLocalTime;
|
||||||
|
begin
|
||||||
|
freemem(transitions);
|
||||||
|
freemem(type_idxs);
|
||||||
|
freemem(types);
|
||||||
|
freemem(zone_names);
|
||||||
|
freemem(leaps);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{
|
||||||
|
$Log$
|
||||||
|
Revision 1.1 1999-12-01 22:46:59 peter
|
||||||
|
+ timezone support
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user