mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-17 23:19:29 +02:00
* android: Use ICU to get timezone information if running on an Android version where libc does not implement timezone.
git-svn-id: trunk@34348 -
This commit is contained in:
parent
f50671fe44
commit
064375ea72
@ -3572,7 +3572,7 @@ endif
|
||||
.NOTPARALLEL:
|
||||
include $(INC)/makefile.inc
|
||||
SYSINCDEPS=$(addprefix $(INC)/,$(SYSINCNAMES))
|
||||
SYSINCDEPS:=$(SYSINCDEPS) sysandroid.inc
|
||||
SYSINCDEPS:=$(SYSINCDEPS) sysandroidh.inc sysandroid.inc
|
||||
include $(PROCINC)/makefile.cpu
|
||||
SYSCPUDEPS=$(addprefix $(PROCINC)/,$(CPUINCNAMES))
|
||||
SYSDEPS=$(SYSINCDEPS) $(SYSCPUDEPS)
|
||||
@ -3598,7 +3598,7 @@ strings$(PPUEXT) : $(INC)/strings.pp $(INC)/stringsi.inc\
|
||||
$(COMPILER) $(INC)/strings.pp
|
||||
unix$(PPUEXT) : $(UNIXINC)/unix.pp strings$(PPUEXT) baseunix$(PPUEXT) $(INC)/textrec.inc $(INC)/filerec.inc \
|
||||
$(LINUXINC)/unxconst.inc $(UNIXINC)/timezone.inc $(SYSTEMUNIT)$(PPUEXT) \
|
||||
$(LINUXINC)/unxfunc.inc unixandroid.inc
|
||||
$(LINUXINC)/unxfunc.inc unixandroid.inc cwstring$(PPUEXT)
|
||||
$(COMPILER) $(UNIXINC)/unix.pp
|
||||
syscall$(PPUEXT) : $(UNIXINC)/syscall.pp $(LINUXINC)/$(ARCH)/syscallh.inc $(LINUXINC)/$(ARCH)/sysnr.inc $(SYSTEMUNIT)$(PPUEXT)
|
||||
$(COMPILER) $(UNIXINC)/syscall.pp
|
||||
@ -3612,7 +3612,7 @@ baseunix$(PPUEXT) : $(UNIXINC)/baseunix.pp $(LINUXINC)/errno.inc $(LINUXINC)/pty
|
||||
$(LINUXINC)/ostypes.inc $(LINUXINC)/osmacro.inc $(UNIXINC)/gensigset.inc \
|
||||
$(UNIXINC)/genfuncs.inc $(SYSTEMUNIT)$(PPUEXT)
|
||||
$(COMPILER) $(UNIXINC)/baseunix.pp
|
||||
dl$(PPUEXT) : $(UNIXINC)/dl.pp $(SYSTEMUNIT)$(PPUEXT) dlandroid.inc
|
||||
dl$(PPUEXT) : $(UNIXINC)/dl.pp $(SYSTEMUNIT)$(PPUEXT) ctypes$(PPUEXT) dlandroid.inc
|
||||
$(COMPILER) $(UNIXINC)/dl.pp
|
||||
dynlibs$(PPUEXT) : $(INC)/dynlibs.pas $(UNIXINC)/dynlibs.inc dl$(PPUEXT) objpas$(PPUEXT)
|
||||
$(COMPILER) $(INC)/dynlibs.pas
|
||||
|
@ -83,7 +83,7 @@ OBJPASDIR=$(RTL)/objpas
|
||||
# SYSINCNAMES
|
||||
include $(INC)/makefile.inc
|
||||
SYSINCDEPS=$(addprefix $(INC)/,$(SYSINCNAMES))
|
||||
SYSINCDEPS:=$(SYSINCDEPS) sysandroid.inc
|
||||
SYSINCDEPS:=$(SYSINCDEPS) sysandroidh.inc sysandroid.inc
|
||||
|
||||
# Get the processor dependent include file names.
|
||||
# This will set the following variables :
|
||||
@ -139,7 +139,7 @@ strings$(PPUEXT) : $(INC)/strings.pp $(INC)/stringsi.inc\
|
||||
|
||||
unix$(PPUEXT) : $(UNIXINC)/unix.pp strings$(PPUEXT) baseunix$(PPUEXT) $(INC)/textrec.inc $(INC)/filerec.inc \
|
||||
$(LINUXINC)/unxconst.inc $(UNIXINC)/timezone.inc $(SYSTEMUNIT)$(PPUEXT) \
|
||||
$(LINUXINC)/unxfunc.inc unixandroid.inc
|
||||
$(LINUXINC)/unxfunc.inc unixandroid.inc cwstring$(PPUEXT)
|
||||
$(COMPILER) $(UNIXINC)/unix.pp
|
||||
|
||||
syscall$(PPUEXT) : $(UNIXINC)/syscall.pp $(LINUXINC)/$(ARCH)/syscallh.inc $(LINUXINC)/$(ARCH)/sysnr.inc $(SYSTEMUNIT)$(PPUEXT)
|
||||
@ -158,7 +158,7 @@ baseunix$(PPUEXT) : $(UNIXINC)/baseunix.pp $(LINUXINC)/errno.inc $(LINUXINC)/pty
|
||||
$(UNIXINC)/genfuncs.inc $(SYSTEMUNIT)$(PPUEXT)
|
||||
$(COMPILER) $(UNIXINC)/baseunix.pp
|
||||
|
||||
dl$(PPUEXT) : $(UNIXINC)/dl.pp $(SYSTEMUNIT)$(PPUEXT) dlandroid.inc
|
||||
dl$(PPUEXT) : $(UNIXINC)/dl.pp $(SYSTEMUNIT)$(PPUEXT) ctypes$(PPUEXT) dlandroid.inc
|
||||
$(COMPILER) $(UNIXINC)/dl.pp
|
||||
|
||||
dynlibs$(PPUEXT) : $(INC)/dynlibs.pas $(UNIXINC)/dynlibs.inc dl$(PPUEXT) objpas$(PPUEXT)
|
||||
|
@ -13,6 +13,79 @@
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**********************************************************************}
|
||||
|
||||
type
|
||||
UErrorCode = SizeInt;
|
||||
int32_t = longint;
|
||||
uint32_t = longword;
|
||||
UBool = LongBool;
|
||||
|
||||
UCalendar = pointer;
|
||||
UCalendarType = longint;
|
||||
UCalendarDisplayNameType = longint;
|
||||
UCalendarDateFields = longint;
|
||||
|
||||
const
|
||||
UCAL_STANDARD = 0;
|
||||
UCAL_SHORT_STANDARD = 1;
|
||||
UCAL_DST = 2;
|
||||
UCAL_SHORT_DST = 3;
|
||||
|
||||
UCAL_ZONE_OFFSET = 15;
|
||||
UCAL_DST_OFFSET = 16;
|
||||
|
||||
var
|
||||
ucal_open: function (zoneID: PUnicodeChar; len: int32_t; locale: PAnsiChar; ctype: UCalendarType; var status: UErrorCode): UCalendar; cdecl;
|
||||
ucal_close: procedure (cal: UCalendar); cdecl;
|
||||
ucal_getTimeZoneDisplayName: function (cal: UCalendar; dtype: UCalendarDisplayNameType; locale: PAnsiChar; result: PUnicodeChar; resultLength: int32_t;
|
||||
var status: UErrorCode): int32_t; cdecl;
|
||||
ucal_inDaylightTime: function (cal: UCalendar; var status: UErrorCode): UBool; cdecl;
|
||||
ucal_get: function (cal: UCalendar; field: UCalendarDateFields; var status: UErrorCode): int32_t; cdecl;
|
||||
|
||||
var
|
||||
TZStandardName: utf8string;
|
||||
TZDaylightName: utf8string;
|
||||
|
||||
function GetIcuProc(const Name: AnsiString; var ProcPtr; libId: longint): boolean; external name 'CWSTRING_GET_ICU_PROC';
|
||||
|
||||
procedure ReadTimeZoneFromICU;
|
||||
var
|
||||
locale: utf8string;
|
||||
tz: unicodestring;
|
||||
res: unicodestring;
|
||||
err: UErrorCode;
|
||||
cal: UCalendar;
|
||||
begin
|
||||
if not GetIcuProc('ucal_open', ucal_open, 1) then exit;
|
||||
if not GetIcuProc('ucal_close', ucal_close, 1) then exit;
|
||||
if not GetIcuProc('ucal_getTimeZoneDisplayName', ucal_getTimeZoneDisplayName, 1) then exit;
|
||||
if not GetIcuProc('ucal_inDaylightTime', ucal_inDaylightTime, 1) then exit;
|
||||
if not GetIcuProc('ucal_get', ucal_get, 1) then exit;
|
||||
|
||||
locale:='en_US';
|
||||
tz:=unicodestring(GetSystemProperty('persist.sys.timezone'));
|
||||
err:=0;
|
||||
cal:=ucal_open(PUnicodeChar(tz), Length(tz), PAnsiChar(locale), 0, err);
|
||||
if cal = nil then
|
||||
exit;
|
||||
tzdaylight:=ucal_inDaylightTime(cal, err);
|
||||
|
||||
SetLength(res, 200);
|
||||
SetLength(res, ucal_getTimeZoneDisplayName(cal, UCAL_SHORT_STANDARD, PAnsiChar(locale), PUnicodeChar(res), Length(res), err));
|
||||
TZStandardName:=utf8string(res);
|
||||
tzname[False]:=PAnsiChar(TZStandardName);
|
||||
|
||||
SetLength(res, 200);
|
||||
SetLength(res, ucal_getTimeZoneDisplayName(cal, UCAL_SHORT_DST, PAnsiChar(locale), PUnicodeChar(res), Length(res), err));
|
||||
TZDaylightName:=utf8string(res);
|
||||
tzname[True]:=PAnsiChar(TZDaylightName);
|
||||
|
||||
Tzseconds:=ucal_get(cal, UCAL_ZONE_OFFSET, err) div 1000;
|
||||
if tzdaylight then
|
||||
Tzseconds:=Tzseconds + ucal_get(cal, UCAL_DST_OFFSET, err) div 1000;
|
||||
|
||||
ucal_close(cal);
|
||||
end;
|
||||
|
||||
type
|
||||
Ptm = ^tm;
|
||||
tm = record
|
||||
@ -34,10 +107,8 @@ function localtime(t: PLongInt): Ptm; cdecl; external 'c' name 'localtime';
|
||||
|
||||
var
|
||||
c_tzname: array[0..1] of PAnsiChar; external 'c' name 'tzname';
|
||||
c_timezone: longint; external 'c' name 'timezone';
|
||||
c_daylignt: shortint; external 'c' name 'daylight';
|
||||
|
||||
procedure InitLocalTime;
|
||||
procedure ReadTimeZoneFromLibC;
|
||||
var
|
||||
t: longint;
|
||||
tt: Ptm;
|
||||
@ -50,10 +121,14 @@ begin
|
||||
begin
|
||||
tzdaylight:=tt^.tm_isdst <> 0;
|
||||
tzseconds:=tt^.tm_gmtoff;
|
||||
end
|
||||
else
|
||||
begin
|
||||
tzdaylight:=c_daylignt <> 0;
|
||||
tzseconds:=-c_timezone;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure InitLocalTime;
|
||||
begin
|
||||
ReadTimeZoneFromLibC;
|
||||
// If cuurent Android version is too old and does not support timezone
|
||||
// in libc, use ICU library.
|
||||
if tzname[false] = nil then
|
||||
ReadTimeZoneFromICU;
|
||||
end;
|
||||
|
@ -15,7 +15,11 @@
|
||||
Unit Unix;
|
||||
Interface
|
||||
|
||||
Uses BaseUnix,UnixType;
|
||||
Uses
|
||||
{$ifdef android}
|
||||
cwstring,
|
||||
{$endif android}
|
||||
BaseUnix,UnixType;
|
||||
// If you deprecated new symbols, please annotate the version.
|
||||
// this makes it easier to decide if they can already be removed.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user