1 { Copyright (C) 2005 Bas Steendijk and Peter Green
\r
2 For conditions of distribution and use, see copyright notice in zlib_license.txt
\r
3 which is included in the package
\r
4 ----------------------------------------------------------------------------- }
\r
6 this unit returns unix timestamp with seconds and microseconds (as float)
\r
7 works on windows/delphi, and on freepascal on unix.
\r
20 irctime,unixtime:integer;
\r
22 settimebias:integer;
\r
23 qpcjump:float; {can be read out and reset for debug purpose}
\r
24 performancecountfreq:extended;
\r
26 function irctimefloat:float;
\r
27 function irctimeint:integer;
\r
29 function unixtimefloat:float;
\r
30 function unixtimeint:integer;
\r
32 function wintimefloat:float;
\r
34 procedure settime(newtime:integer);
\r
35 procedure gettimezone;
\r
36 procedure timehandler;
\r
39 function timestring(i:integer):string;
\r
40 function timestrshort(i:integer):string;
\r
42 function oletounixfloat(t:float):float;
\r
43 function oletounix(t:tdatetime):integer;
\r
44 function unixtoole(i:integer):tdatetime;
\r
47 timefloatbias:float;
\r
48 lastunixtimefloat:float=0;
\r
61 baseunix,unix,unixutil,{needed for 2.0.2}
\r
68 {$include unixstuff.inc}
\r
72 daysdifference=25569;
\r
74 function oletounixfloat(t:float):float;
\r
76 t := (t - daysdifference) * 86400;
\r
80 function oletounix(t:tdatetime):integer;
\r
82 result := trunc(oletounixfloat(t));
\r
85 function unixtoole(i:integer):tdatetime;
\r
87 result := ((i)/86400)+daysdifference;
\r
91 {-----------------------------------------*nix/freepascal code to read time }
\r
93 function unixtimefloat:float;
\r
98 result := tv.tv_sec+(tv.tv_usec/1000000);
\r
101 function wintimefloat:extended;
\r
103 result := unixtimefloat;
\r
106 function unixtimeint:integer;
\r
111 result := tv.tv_sec;
\r
115 {------------------------------ windows/delphi code to read time}
\r
117 { free pascals tsystemtime is incomaptible with windows api calls
\r
118 so we declare it ourselves - plugwash
\r
122 TSystemTime = record
\r
130 wMilliseconds: Word;
\r
133 function Date_utc: extended;
\r
135 SystemTime: TSystemTime;
\r
138 GetsystemTime(@SystemTime);
\r
140 GetsystemTime(SystemTime);
\r
142 with SystemTime do Result := EncodeDate(wYear, wMonth, wDay);
\r
145 function Time_utc: extended;
\r
147 SystemTime: TSystemTime;
\r
150 GetsystemTime(@SystemTime);
\r
152 GetsystemTime(SystemTime);
\r
155 Result := EncodeTime(wHour, wMinute, wSecond, wMilliSeconds);
\r
158 function Now_utc: extended;
\r
160 Result := round(Date_utc) + Time_utc;
\r
164 highdwordconst=4294967296.0;
\r
166 function wintimefloat:extended;
\r
172 p2:tlargeinteger absolute p;
\r
175 if performancecountfreq = 0 then begin
\r
176 QueryPerformancefrequency(p2);
\r
178 if e < 0 then e := e + highdwordconst;
\r
179 performancecountfreq := ((p.highpart*highdwordconst)+e);
\r
181 queryperformancecounter(p2);
\r
183 if e < 0 then e := e + highdwordconst;
\r
184 result := ((p.highpart*highdwordconst)+e)/performancecountfreq;
\r
188 classpriority,threadpriority:integer;
\r
192 hprocess,hthread:integer;
\r
194 hProcess := GetCurrentProcess;
\r
195 hThread := GetCurrentThread;
\r
197 ClassPriority := GetPriorityClass(hProcess);
\r
198 ThreadPriority := GetThreadPriority(hThread);
\r
200 SetPriorityClass(hProcess, REALTIME_PRIORITY_CLASS);
\r
201 SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
\r
206 hprocess,hthread:integer;
\r
208 hProcess := GetCurrentProcess;
\r
209 hThread := GetCurrentThread;
\r
211 SetPriorityClass(hProcess, ClassPriority);
\r
212 SetThreadPriority(hThread, ThreadPriority);
\r
215 function unixtimefloat:float;
\r
219 if timefloatbias = 0 then begin
\r
222 repeat g := now_utc; h := wintimefloat until g > f;
\r
223 timefloatbias := oletounixfloat(g)-h;
\r
226 result := wintimefloat+timefloatbias;
\r
229 workaround for QPC jumps
\r
230 (approach 2: always check "hi res" QPC unixtime against the "guaranteed" systemtime one)
\r
232 f := result-(oletounixfloat(now_utc));
\r
233 if abs(f) > 0.02 then begin
\r
234 f := timefloatbias;
\r
235 timefloatbias := 0;
\r
236 result := unixtimefloat;
\r
237 qpcjump := qpcjump + f - timefloatbias;
\r
240 if (result <= lastunixtimefloat) then result := lastunixtimefloat + 0.0000001;
\r
241 lastunixtimefloat := result;
\r
244 function unixtimeint:integer;
\r
246 result := trunc(unixtimefloat);
\r
250 {-----------------------------------------------end of platform specific}
\r
252 function irctimefloat:float;
\r
254 result := unixtimefloat+settimebias;
\r
257 function irctimeint:integer;
\r
259 result := unixtimeint+settimebias;
\r
263 procedure settime(newtime:integer);
\r
267 a := irctimeint-settimebias;
\r
268 if newtime = 0 then settimebias := 0 else settimebias := newtime-a;
\r
270 irctime := irctimeint;
\r
273 procedure timehandler;
\r
275 if unixtime = 0 then init;
\r
276 unixtime := unixtimeint;
\r
277 irctime := irctimeint;
\r
278 if unixtime and 63 = 0 then begin
\r
279 {update everything, apply timezone changes, clock changes, etc}
\r
281 timefloatbias := 0;
\r
282 unixtime := unixtimeint;
\r
283 irctime := irctimeint;
\r
288 procedure gettimezone;
\r
304 timezone := tzseconds;
\r
307 timezone := (longint(hh) * 3600 + mm * 60 + ss) - (unixtimeint mod 86400);
\r
310 timezone := round((now-now_utc)*86400);
\r
313 while timezone > 43200 do dec(timezone,86400);
\r
314 while timezone < -43200 do inc(timezone,86400);
\r
316 if timezone >= 0 then timezonestr := '+' else timezonestr := '-';
\r
317 l := abs(timezone) div 60;
\r
318 timezonestr := timezonestr + char(l div 600 mod 10+48)+char(l div 60 mod 10+48)+':'+char(l div 10 mod 6+48)+char(l mod 10+48);
\r
321 function timestrshort(i:integer):string;
\r
323 weekday:array[0..6] of string[4]=('Thu','Fri','Sat','Sun','Mon','Tue','Wed');
\r
324 month:array[0..11] of string[4]=('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
\r
326 y,m,d,h,min,sec,ms:word;
\r
329 t := unixtoole(i+timezone);
\r
330 decodedate(t,y,m,d);
\r
331 decodetime(t,h,min,sec,ms);
\r
332 result := weekday[(i+timezone) div 86400 mod 7]+' '+month[m-1]+' '+inttostr(d)+' '+
\r
333 inttostr(h div 10)+inttostr(h mod 10)+':'+inttostr(min div 10)+inttostr(min mod 10)+':'+inttostr(sec div 10)+inttostr(sec mod 10)+' '+
\r
337 function timestring(i:integer):string;
\r
339 weekday:array[0..6] of string[10]=('Thursday','Friday','Saturday','Sunday','Monday','Tuesday','Wednesday');
\r
340 month:array[0..11] of string[10]=('January','February','March','April','May','June','July','August','September','October','November','December');
\r
342 y,m,d,h,min,sec,ms:word;
\r
345 t := unixtoole(i+timezone);
\r
346 decodedate(t,y,m,d);
\r
347 decodetime(t,h,min,sec,ms);
\r
348 result := weekday[(i+timezone) div 86400 mod 7]+' '+month[m-1]+' '+inttostr(d)+' '+inttostr(y)+' -- '+
\r
349 inttostr(h div 10)+inttostr(h mod 10)+':'+inttostr(min div 10)+inttostr(min mod 10)+':'+inttostr(sec div 10)+inttostr(sec mod 10)+' '+
\r
358 unixtime := unixtimeint;
\r
359 irctime := irctimeint;
\r