(*
/*

CLASS {NATIVE_Date_time|_Delphi_FPC}, ABSTRACT, NATIVE, TESTED,
ABSTRACT :

NATIVE: "///COPY NATIVE_Date_time.pas" .

CONST STR :
    NATIVE_Date_time_import = @
    "uses NATIVE_Date_time"
    "	{$IFDEF _D6orHigher}"     
    "	  , DateUtils "
    "	{$ENDIF}"     
	"	{$IFDEF LINUX}"
	"	{$ELSE}"
	"		, Windows "
	"	{$ENDIF};"
    
    NATIVE_Date = @
    "   try "
    "       Result := EncodeDate(X_Year, X_Month, X_Day) * 24.0 * 3600000;"
    "   except on E: Exception do begin"
    "       Any_exception(E); end;"
    "   end;"
    
    NATIVE_Now = @
    "   Result := Now * 24.0 * 3600000;"
    
    NATIVE_UTC_now = @
    "	RESULT := Do_UTC_Now * 24.0 * 3600000;"
    
    NATIVE_Year = @
    "   Result := YearOf(X_D / 24.0 / 3600000);"
    
    NATIVE_Month = @
    "   Result := MonthOf(X_D / 24.0 / 3600000);"
    
    NATIVE_Day = @
    "   Result := DayOf(X_D / 24.0 / 3600000);"
    
    NATIVE_Week_day = @
    "   Result := DayOfWeek(X_D / 24.0 / 3600000) - 1;"
    
    NATIVE_Hour = @
    "   Result := HourOf(X_D / 24.0 / 3600000);"
    
    NATIVE_Minute = @
    "   Result := MinuteOf(X_D / 24.0 / 3600000);"
    
    NATIVE_Second = @
    "   Result := SecondOf(X_D / 24.0 / 3600000);"
    
    NATIVE_Millisecond = @
    "   Result := MillisecondOf(X_D / 24.0 / 3600000);"

    NATIVE_Day_of_year = @
    "   Result := DayOfTheYear(X_D / 24.0 / 3600000);"
    
    NATIVE_Days_in_month = @
    "   Result := DaysInAMonth(YearOf(X_D / 24.0 / 3600000),"
    "		MonthOf(X_D / 24.0 / 3600000));"
    
    NATIVE_Date_time_Str = @
    "    Result := DateTimeToStr(X_D / 24.0 / 3600000);"
    // DateTimeToStr is not thread-safe!

    .
         
END
*/
*)
unit NATIVE_Date_time;

interface

{$IFDEF VER90}
              {$DEFINE _D2}
              {$DEFINE _D2orD3}
              {$DEFINE _D2orD3orD4}
{$ENDIF}

{$IFDEF VER100}
              {$DEFINE _D3}
              {$DEFINE _D3orHigher}
              {$DEFINE _D2orD3}
              {$DEFINE _D2orD3orD4}
              {$DEFINE _D3orD4}
{$ENDIF}

{$IFDEF VER120}
              {$DEFINE _D3orHigher}
              {$DEFINE _D3orD4}
              {$DEFINE _D4}
              {$DEFINE _D4orHigher}
              {$DEFINE _D2orD3orD4}
                  {$IFnDEF KOL_MCK}
                           {$DEFINE INPACKAGE}
                  {$ENDIF}
{$ENDIF}

{$IFDEF VER130}
              {$DEFINE _D3orHigher}
              {$DEFINE _D4orHigher}
              {$DEFINE _D5}
              {$DEFINE _D5orHigher}
{$ENDIF}

{$IFDEF VER140}
              {$DEFINE _D3orHigher}
              {$DEFINE _D4orHigher}
              {$DEFINE _D5orHigher}
              {$DEFINE _D6}
              {$DEFINE _D6orHigher}
{$ENDIF}

{$IFDEF VER150}
              {$DEFINE _D3orHigher}
              {$DEFINE _D4orHigher}
              {$DEFINE _D5orHigher}
              {$DEFINE _D6orHigher}
              {$DEFINE _D7}
              {$DEFINE _D7orHigher}
{$WARN UNIT_DEPRECATED OFF}
{$WARN SYMBOL_PLATFORM OFF}
{$WARN UNSAFE_TYPE OFF}
{$WARN UNSAFE_CAST OFF}
{$WARN UNSAFE_CODE OFF}
{$ENDIF}

uses 
	 {$IFDEF _D6orHigher}
	 	DateUtils,
	 {$ENDIF}
	 	SysUtils
	 	{$IFDEF LINUX}
	 		, DateUtils
	 	{$ELSE}
	 		, Windows
	 	{$ENDIF}
	 ;


function Do_UTC_Now: Double; 

{$IFnDEF _D6orHigher}
function YearOf(const AValue: TDateTime): Word;
function MonthOf(const AValue: TDateTime): Word;
function DayOf(const AValue: TDateTime): Word;
function HourOf(const AValue: TDateTime): Word;
function MinuteOf(const AValue: TDateTime): Word;
function SecondOf(const AValue: TDateTime): Word;
function MilliSecondOf(const AValue: TDateTime): Word;
function DayOfTheYear(const AValue: TDateTime): Word;
function DaysInAMonth(const AYear, AMonth: Word): Word;
{$ENDIF}

implementation

function Do_UTC_Now: Double;
{$IFnDEF LINUX}
var ST: TSystemTime;
{$ENDIF}
begin
 	 {$IFDEF LINUX}
 	 	Result := LocalTimeToUniversal(Now);
 	 {$ELSE}
		     GetSystemTime(ST);
		     Result := SystemTimeToDateTime(ST);
 	 {$ENDIF}
end; 

{$IFnDEF _D6orHigher}
function YearOf(const AValue: TDateTime): Word;
var
  LMonth, LDay: Word;
begin
  DecodeDate(AValue, Result, LMonth, LDay);
end;

function MonthOf(const AValue: TDateTime): Word;
var
  LYear, LDay: Word;
begin
  DecodeDate(AValue, LYear, Result, LDay);
end;

function DayOf(const AValue: TDateTime): Word;
var
  LYear, LMonth: Word;
begin
  DecodeDate(AValue, LYear, LMonth, Result);
end;

function HourOf(const AValue: TDateTime): Word;
var
  LMinute, LSecond, LMilliSecond: Word;
begin
  DecodeTime(AValue, Result, LMinute, LSecond, LMilliSecond);
end;

function MinuteOf(const AValue: TDateTime): Word;
var
  LHour, LSecond, LMilliSecond: Word;
begin
  DecodeTime(AValue, LHour, Result, LSecond, LMilliSecond);
end;

function SecondOf(const AValue: TDateTime): Word;
var
  LHour, LMinute, LMilliSecond: Word;
begin
  DecodeTime(AValue, LHour, LMinute, Result, LMilliSecond);
end;

function MilliSecondOf(const AValue: TDateTime): Word;
var
  LHour, LMinute, LSecond: Word;
begin
  DecodeTime(AValue, LHour, LMinute, LSecond, Result);
end;

function StartOfTheYear(const AValue: TDateTime): TDateTime;
begin
  Result := EncodeDate(YearOf(AValue), 1, 1);
end;

function DayOfTheYear(const AValue: TDateTime): Word;
begin
  Result := Trunc(AValue - StartOfTheYear(AValue)) + 1;
end;

const
  MonthDays: array [Boolean] of TDayTable =
    ((31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31),
     (31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31));

function IsLeapYear(Year: Word): Boolean;
begin
  Result := (Year mod 4 = 0) and ((Year mod 100 <> 0) or (Year mod 400 = 0));
end;

function DaysInAMonth(const AYear, AMonth: Word): Word;
begin
  Result := MonthDays[(AMonth = 2) and IsLeapYear(AYear), AMonth];
end;

{$ENDIF}

end.
