{$MODE FPC}
{$MODESWITCH OUT}
{$MODESWITCH RESULT}
unit dclock;

interface

//
//  GetUnixTimestamp
//
//      Returns the number of seconds since 00:00 hours, Jan 1, 1970 UTC (i.e.,
//      the current unix timestamp).
//
function GetUnixTimestamp: PtrInt;

//
//  GetUTCOffset
//
//      Returns local UTC offset in seconds. That isTimeZoneInformation.Bias,
//
//          UnixTimestamp = UnixTimestampLocal + UTCOffset
//
function GetUTCOffset: PtrInt;

//
//  GetUnixTimestampLocal
//
//      Returns the number of seconds since 00:00 hours, Jan 1, 1970 Local.
//
function GetUnixTimestampLocal: PtrInt;

implementation

{$IF Defined(WINDOWS)}
uses
  windows;
{$ENDIF}

{$IF Defined(UNIX)}
uses
  BaseUnix,
  Unix, // <- initializes tzseconds
  UnixUtil; // <- declares tzseconds
{$ENDIF}

{$IF Defined(WINDOWS)}
{$DEFINE TIME_IMPLEMENTED}
function GetUnixTimestamp: PtrInt;
var
  F: FILETIME;
  Temp: Int64;
begin
  GetSystemTimeAsFileTime(F);
  Temp := (Int64(F.dwLowDateTime) + (Int64(F.dwHighDateTime) shl 32) - 116444736000000000) div 10000000;
  Result := Temp;
end;

function GetUTCOffset: PtrInt;
var
  TimeZoneInformation: TIME_ZONE_INFORMATION;
begin
  if GetTimeZoneInformation(TimeZoneInformation) <> TIME_ZONE_ID_INVALID then begin
    Result := TimeZoneInformation.Bias * 60;
  end else
    Result := 0;
end;

function GetUnixTimestampLocal: PtrInt;
var
  G, F: FILETIME;
  Temp: Int64;
begin
  GetSystemTimeAsFileTime(G);
  FileTimeToLocalFileTime(G, F);
  Temp := (Int64(F.dwLowDateTime) + (Int64(F.dwHighDateTime) shl 32) - 116444736000000000) div 10000000;
  Result := Temp;
end;
{$ENDIF}

{$IF Defined(UNIX)}
{$DEFINE TIME_IMPLEMENTED}
function GetUnixTimestamp: PtrInt;
begin
  Result := FpTime();
end;

function GetUTCOffset: PtrInt; inline;
begin
  Result := {$IF Declared(TzSeconds)}-TzSeconds
    {$ELSE}0 {$WARNING UnixUtil.TzSeconds is not defined, GetUnixTimestampLocal returns global time}{$ENDIF};
end;

function GetUnixTimestampLocal: PtrInt;
begin
  Result := FpTime() - GetUTCOffset;
end;
{$ENDIF}

{$IF not Defined(TIME_IMPLEMENTED)}
{$WARNING dclock.GetUnixTimestamp is not implemented for specified platform, it will always return zero}
function GetUnixTimestamp: PtrInt;
begin
  Result := 0;
end;

function GetUTCOffset: PtrInt;
begin
  Result := 0;
end;

function GetUnixTimestampLocal: PtrInt;
begin
  Result := 0;
end;
{$ENDIF}

end.
