timezone.inc 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. {
  2. $Id$
  3. Support for timezone info in /usr/share/timezone
  4. }
  5. type
  6. plongint=^longint;
  7. pbyte=^byte;
  8. ttzhead=packed record
  9. tzh_reserved : array[0..19] of byte;
  10. tzh_ttisgmtcnt,
  11. tzh_ttisstdcnt,
  12. tzh_leapcnt,
  13. tzh_timecnt,
  14. tzh_typecnt,
  15. tzh_charcnt : longint;
  16. end;
  17. pttinfo=^tttinfo;
  18. tttinfo=packed record
  19. offset : longint;
  20. isdst : boolean;
  21. idx : byte;
  22. isstd : byte;
  23. isgmt : byte;
  24. end;
  25. pleap=^tleap;
  26. tleap=record
  27. transition : longint;
  28. change : longint;
  29. end;
  30. var
  31. num_transitions,
  32. num_leaps,
  33. num_types : longint;
  34. transitions : plongint;
  35. type_idxs : pbyte;
  36. types : pttinfo;
  37. zone_names : pchar;
  38. leaps : pleap;
  39. function find_transition(timer:longint):pttinfo;
  40. var
  41. i : longint;
  42. begin
  43. if (num_transitions=0) or (timer<transitions[0]) then
  44. begin
  45. i:=0;
  46. while (i<num_types) and (types[i].isdst) do
  47. inc(i);
  48. if (i=num_types) then
  49. i:=0;
  50. end
  51. else
  52. begin
  53. for i:=1 to num_transitions do
  54. if (timer<transitions[i]) then
  55. break;
  56. i:=type_idxs[i-1];
  57. end;
  58. find_transition:=@types[i];
  59. end;
  60. procedure GetLocalTimezone(timer:longint;var leap_correct,leap_hit:longint);
  61. var
  62. info : pttinfo;
  63. i : longint;
  64. begin
  65. info:=find_transition(timer);
  66. TZDaylight:=info^.isdst;
  67. TZSeconds:=info^.offset;
  68. i:=0;
  69. while (i<num_types) and (i<2) do
  70. begin
  71. tzname[types[i].isdst]:=@zone_names[types[i].idx];
  72. inc(i);
  73. end;
  74. tzname[info^.isdst]:=@zone_names[info^.idx];
  75. leap_correct:=0;
  76. leap_hit:=0;
  77. i:=num_leaps;
  78. while (i>0) do
  79. begin
  80. if (timer>leaps[i].transition) then
  81. break;
  82. dec(i);
  83. end;
  84. leap_correct:=leaps[i].change;
  85. if (timer=leaps[i].transition) and
  86. (((i=0) and (leaps[i].change>0)) or
  87. (leaps[i].change>leaps[i-1].change)) then
  88. begin
  89. leap_hit:=1;
  90. while (i>0) and
  91. (leaps[i].transition=leaps[i-1].transition+1) and
  92. (leaps[i].change=leaps[i-1].change+1) do
  93. begin
  94. inc(leap_hit);
  95. dec(i);
  96. end;
  97. end;
  98. end;
  99. procedure GetLocalTimezone(timer:longint);
  100. var
  101. lc,lh : longint;
  102. begin
  103. GetLocalTimezone(timer,lc,lh);
  104. end;
  105. procedure ReadTimezoneFile(fn:string);
  106. procedure decode(var l:longint);
  107. var
  108. k : longint;
  109. p : pbyte;
  110. begin
  111. p:=pbyte(@l);
  112. if (p[0] and (1 shl 7))<>0 then
  113. k:=not 0
  114. else
  115. k:=0;
  116. k:=(k shl 8) or p[0];
  117. k:=(k shl 8) or p[1];
  118. k:=(k shl 8) or p[2];
  119. k:=(k shl 8) or p[3];
  120. l:=k;
  121. end;
  122. var
  123. f : longint;
  124. tzdir : string;
  125. tzhead : ttzhead;
  126. i : longint;
  127. chars : longint;
  128. buf : pbyte;
  129. begin
  130. if fn='' then
  131. fn:='localtime';
  132. if fn[1]<>'/' then
  133. begin
  134. tzdir:=getenv('TZDIR');
  135. if tzdir='' then
  136. tzdir:='/usr/share/zoneinfo';
  137. if tzdir[length(tzdir)]<>'/' then
  138. tzdir:=tzdir+'/';
  139. fn:=tzdir+fn;
  140. end;
  141. f:=fdopen(fn,Open_RdOnly);
  142. if f<0 then
  143. exit;
  144. i:=fdread(f,tzhead,sizeof(tzhead));
  145. if i<>sizeof(tzhead) then
  146. exit;
  147. decode(tzhead.tzh_timecnt);
  148. decode(tzhead.tzh_typecnt);
  149. decode(tzhead.tzh_charcnt);
  150. decode(tzhead.tzh_leapcnt);
  151. decode(tzhead.tzh_ttisstdcnt);
  152. decode(tzhead.tzh_ttisgmtcnt);
  153. num_transitions:=tzhead.tzh_timecnt;
  154. num_types:=tzhead.tzh_typecnt;
  155. chars:=tzhead.tzh_charcnt;
  156. reallocmem(transitions,num_transitions*sizeof(longint));
  157. reallocmem(type_idxs,num_transitions);
  158. reallocmem(types,num_types*sizeof(tttinfo));
  159. reallocmem(zone_names,chars);
  160. reallocmem(leaps,num_leaps*sizeof(tleap));
  161. fdread(f,transitions^,num_transitions*4);
  162. fdread(f,type_idxs^,num_transitions);
  163. for i:=0 to num_transitions-1 do
  164. decode(transitions[i]);
  165. for i:=0 to num_types-1 do
  166. begin
  167. fdread(f,types[i].offset,4);
  168. fdread(f,types[i].isdst,1);
  169. fdread(f,types[i].idx,1);
  170. decode(types[i].offset);
  171. types[i].isstd:=0;
  172. types[i].isgmt:=0;
  173. end;
  174. fdread(f,zone_names^,chars);
  175. for i:=0 to num_leaps-1 do
  176. begin
  177. fdread(f,leaps[i].transition,4);
  178. fdread(f,leaps[i].change,4);
  179. decode(leaps[i].transition);
  180. decode(leaps[i].change);
  181. end;
  182. getmem(buf,tzhead.tzh_ttisstdcnt);
  183. fdread(f,buf^,tzhead.tzh_ttisstdcnt);
  184. for i:=0 to tzhead.tzh_ttisstdcnt-1 do
  185. types[i].isstd:=byte(buf[i]<>0);
  186. freemem(buf);
  187. getmem(buf,tzhead.tzh_ttisgmtcnt);
  188. fdread(f,buf^,tzhead.tzh_ttisgmtcnt);
  189. for i:=0 to tzhead.tzh_ttisgmtcnt-1 do
  190. types[i].isgmt:=byte(buf[i]<>0);
  191. freemem(buf);
  192. fdclose(f);
  193. end;
  194. function GetTimezoneFile:string;
  195. var
  196. f,len : longint;
  197. s : string;
  198. begin
  199. GetTimezoneFile:='';
  200. f:=fdopen('/etc/timezone',Open_RdOnly);
  201. if f=0 then
  202. exit;
  203. len:=fdread(f,s[1],high(s));
  204. s[0]:=chr(len);
  205. len:=pos(#10,s);
  206. if len<>0 then
  207. s[0]:=chr(len-1);
  208. fdclose(f);
  209. GetTimezoneFile:=s;
  210. end;
  211. procedure InitLocalTime;
  212. begin
  213. ReadTimezoneFile(GetTimezoneFile);
  214. GetLocalTimezone(GetTimeOfDay);
  215. end;
  216. procedure DoneLocalTime;
  217. begin
  218. freemem(transitions);
  219. freemem(type_idxs);
  220. freemem(types);
  221. freemem(zone_names);
  222. freemem(leaps);
  223. end;
  224. {
  225. $Log$
  226. Revision 1.1 1999-12-01 22:46:59 peter
  227. + timezone support
  228. }