1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
{
*****************************************************************************
This file is part of LazUtils.
See the file COPYING.modifiedLGPL.txt, included in this distribution,
for details about the license.
*****************************************************************************
}
unit LazSysUtils;
{$mode objfpc}{$H+}
interface
uses
SysUtils;
function NowUTC: TDateTime;
function GetTickCount64: QWord;
implementation
uses
{$IFDEF Windows}
Windows,
{$ELSE}
{$IFnDEF HASAMIGA}
Unix, BaseUnix,
{$If defined(Linux) and (FPC_FULLVERSION<30000)}
Linux,
{$EndIf}
{$ENDIF}
{$ENDIF}
Classes;
{$IF FPC_FULLVERSION>=30000}
function GetTickCount64: QWord;
begin
Result := SysUtils.GetTickCount64;
end;
{$ENDIF}
// ToDo: Move the code to 1 include file per platform
{$IFDEF WINDOWS}
function NowUTC: TDateTime;
var
SystemTime: TSystemTime;
begin
windows.GetSystemTime(SystemTime{%H-});
result := systemTimeToDateTime(SystemTime);
end;
{$IF FPC_FULLVERSION<30000}
function GetTickCount64: QWord;
begin
// GetTickCount64 is better, but we need to check the Windows version to use it
Result := Windows.GetTickCount();
end;
{$ENDIF FPC_FULLVERSION}
{$ELSE WINDOWS}
{$IFDEF UNIX}
Const
{Date Translation}
C1970=2440588;
D0 = 1461;
D1 = 146097;
D2 =1721119;
Procedure JulianToGregorian(JulianDN:LongInt;out Year,Month,Day:Word);
Var
YYear,XYear,Temp,TempMonth : LongInt;
Begin
Temp:=((JulianDN-D2) shl 2)-1;
JulianDN:=Temp Div D1;
XYear:=(Temp Mod D1) or 3;
YYear:=(XYear Div D0);
Temp:=((((XYear mod D0)+4) shr 2)*5)-3;
Day:=((Temp Mod 153)+5) Div 5;
TempMonth:=Temp Div 153;
If TempMonth>=10 Then
Begin
inc(YYear);
dec(TempMonth,12);
End;
inc(TempMonth,3);
Month := TempMonth;
Year:=YYear+(JulianDN*100);
end;
Procedure EpochToLocal(epoch:longint;out year,month,day,hour,minute,second:Word);
{
Transforms Epoch time into local time (hour, minute,seconds)
}
Var
DateNum: LongInt;
Begin
Datenum:=(Epoch Div 86400) + c1970;
JulianToGregorian(DateNum,Year,Month,day);
Epoch:=Abs(Epoch Mod 86400);
Hour:=Epoch Div 3600;
Epoch:=Epoch Mod 3600;
Minute:=Epoch Div 60;
Second:=Epoch Mod 60;
End;
function NowUTC: TDateTime;
var
tz:timeval;
SystemTime: TSystemTime;
begin
fpgettimeofday(@tz,nil);
EpochToLocal(tz.tv_sec,SystemTime.year,SystemTime.month,SystemTime.day,SystemTime.hour,SystemTime.Minute,SystemTime.Second);
SystemTime.MilliSecond:=tz.tv_usec div 1000;
result := systemTimeToDateTime(SystemTime);
end;
{$IF FPC_FULLVERSION<30000}
{$IF defined(Linux) and not defined(GetTickCountTimeOfDay)}
function GetTickCount64: QWord;
var
tp: timespec;
begin
clock_gettime(CLOCK_MONOTONIC, @tp); // exists since Linux Kernel 2.6
Result := (Int64(tp.tv_sec) * 1000) + (tp.tv_nsec div 1000000);
end;
{$ELSE}
function GetTickCount64: QWord;
var
tp: TTimeVal;
begin
fpgettimeofday(@tp, nil);
Result := (Int64(tp.tv_sec) * 1000) + (tp.tv_usec div 1000);
end;
{$ENDIF}
{$ENDIF FPC_FULLVERSION}
{$ELSE UNIX}
// Not Windows and not UNIX, so just write the most trivial code until we have something better:
function NowUTC: TDateTime;
begin
Result := Now;
end;
{$IF FPC_FULLVERSION<30000}
function GetTickCount64: QWord;
begin
Result := Trunc(Now * 24 * 60 * 60 * 1000);
end;
{$ENDIF FPC_FULLVERSION}
{$ENDIF UNIX}
{$ENDIF WINDOWS}
end.
|