unixandroid.inc 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2016 by Yury Sidorov,
  4. member of the Free Pascal development team.
  5. Android-specific part of the System unit.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. type
  13. UErrorCode = SizeInt;
  14. int32_t = longint;
  15. uint32_t = longword;
  16. UBool = LongBool;
  17. UCalendar = pointer;
  18. UCalendarType = longint;
  19. UCalendarDisplayNameType = longint;
  20. UCalendarDateFields = longint;
  21. const
  22. UCAL_STANDARD = 0;
  23. UCAL_SHORT_STANDARD = 1;
  24. UCAL_DST = 2;
  25. UCAL_SHORT_DST = 3;
  26. UCAL_ZONE_OFFSET = 15;
  27. UCAL_DST_OFFSET = 16;
  28. var
  29. ucal_open: function (zoneID: PUnicodeChar; len: int32_t; locale: PAnsiChar; ctype: UCalendarType; var status: UErrorCode): UCalendar; cdecl;
  30. ucal_close: procedure (cal: UCalendar); cdecl;
  31. ucal_getTimeZoneDisplayName: function (cal: UCalendar; dtype: UCalendarDisplayNameType; locale: PAnsiChar; result: PUnicodeChar; resultLength: int32_t;
  32. var status: UErrorCode): int32_t; cdecl;
  33. ucal_inDaylightTime: function (cal: UCalendar; var status: UErrorCode): UBool; cdecl;
  34. ucal_get: function (cal: UCalendar; field: UCalendarDateFields; var status: UErrorCode): int32_t; cdecl;
  35. var
  36. TZStandardName: utf8string;
  37. TZDaylightName: utf8string;
  38. GetIcuProc: function (const Name: AnsiString; var ProcPtr; libId: longint): boolean; external name 'ANDROID_GET_ICU_PROC';
  39. procedure ReadTimeZoneFromICU;
  40. var
  41. locale: utf8string;
  42. tz: unicodestring;
  43. res: unicodestring;
  44. err: UErrorCode;
  45. cal: UCalendar;
  46. begin
  47. if not Assigned(GetIcuProc) then exit;
  48. if not GetIcuProc('ucal_open', ucal_open, 1) then exit;
  49. if not GetIcuProc('ucal_close', ucal_close, 1) then exit;
  50. if not GetIcuProc('ucal_getTimeZoneDisplayName', ucal_getTimeZoneDisplayName, 1) then exit;
  51. if not GetIcuProc('ucal_inDaylightTime', ucal_inDaylightTime, 1) then exit;
  52. if not GetIcuProc('ucal_get', ucal_get, 1) then exit;
  53. locale:='en_US';
  54. tz:=unicodestring(GetSystemProperty('persist.sys.timezone'));
  55. err:=0;
  56. cal:=ucal_open(PUnicodeChar(tz), Length(tz), PAnsiChar(locale), 0, err);
  57. if cal = nil then
  58. exit;
  59. tzdaylight:=ucal_inDaylightTime(cal, err);
  60. SetLength(res, 200);
  61. SetLength(res, ucal_getTimeZoneDisplayName(cal, UCAL_SHORT_STANDARD, PAnsiChar(locale), PUnicodeChar(res), Length(res), err));
  62. TZStandardName:=utf8string(res);
  63. tzname[False]:=PAnsiChar(TZStandardName);
  64. SetLength(res, 200);
  65. SetLength(res, ucal_getTimeZoneDisplayName(cal, UCAL_SHORT_DST, PAnsiChar(locale), PUnicodeChar(res), Length(res), err));
  66. TZDaylightName:=utf8string(res);
  67. tzname[True]:=PAnsiChar(TZDaylightName);
  68. Tzseconds:=ucal_get(cal, UCAL_ZONE_OFFSET, err) div 1000;
  69. if tzdaylight then
  70. Tzseconds:=Tzseconds + ucal_get(cal, UCAL_DST_OFFSET, err) div 1000;
  71. ucal_close(cal);
  72. end;
  73. type
  74. Ptm = ^tm;
  75. tm = record
  76. tm_sec : longint;
  77. tm_min : longint;
  78. tm_hour : longint;
  79. tm_mday : longint;
  80. tm_mon : longint;
  81. tm_year : longint;
  82. tm_wday : longint;
  83. tm_yday : longint;
  84. tm_isdst : longint;
  85. case boolean of
  86. false : (tm_gmtoff : longint;tm_zone : Pchar);
  87. true : (__tm_gmtoff : longint;__tm_zone : Pchar);
  88. end;
  89. function localtime(t: Ptime_t): Ptm; cdecl; external 'c' name 'localtime';
  90. var
  91. c_tzname: array[0..1] of PAnsiChar; external 'c' name 'tzname';
  92. function ReadTimeZoneFromLibC: boolean;
  93. var
  94. t: time_t;
  95. tt: Ptm;
  96. begin
  97. ReadTimeZoneFromLibC:=False;
  98. tzname[false]:=c_tzname[0];
  99. tzname[true]:=c_tzname[1];
  100. t:=fptime;
  101. tt:=localtime(@t);
  102. if tt <> nil then
  103. begin
  104. tzdaylight:=tt^.tm_isdst <> 0;
  105. tzseconds:=tt^.tm_gmtoff;
  106. ReadTimeZoneFromLibC:=tzname[false] <> nil;
  107. end;
  108. end;
  109. procedure InitLocalTime;
  110. begin
  111. if (SystemApiLevel <= 10) or not ReadTimeZoneFromLibC then
  112. // If current Android version is too old and does not support timezone
  113. // in libc, use ICU library.
  114. ReadTimeZoneFromICU;
  115. end;