unit NATIVE_Date_time;

interface

uses Windows, KOL;

function DateTime2SystemTime(
const DateTime : TDateTime; var SystemTime : TSystemTime ) : Boolean;

implementation

{$IFDEF PAS_ONLY}
	{$IFnDEF _D6orHigher}
		{$DEFINE ASM}
	{$ENDIF}
{$ELSE} {$DEFINE ASM}
{$ENDIF}

{$IFDEF ASM}
function DateTime2SystemTime(const DateTime : TDateTime; var SystemTime : TSystemTime ) : Boolean;
asm
    PUSH  EDI
    XCHG  EDI, EAX
    FLD   qword ptr [DateTime]
    FSUB  dword ptr [@@date1601]
    FLD   tbyte ptr [@@nsecsperday]
    DB    $DE, $C9 //FMULP ST(1)
    JMP   @@truncD7
@@date1601: DB $50, $AC, $0E, $49
@@nsecsperday: DB 0,0,0,0,$C0,$69,$2A,$C9,$26,$40
@@truncD7:     CALL  System.@TRUNC
    PUSH  EDX
    PUSH  EAX
    MOV   EAX, ESP
    PUSH  EDI
    PUSH  EAX
    CALL  Windows.FileTimeToSystemTime
    POP   ECX
    POP   ECX
    CMP   EAX, 1
    SBB   EAX, EAX
    INC   EAX
    POP   EDI
end;
{$ELSE}
function DateTime2SystemTime(const DateTime : TDateTime; var SystemTime : TSystemTime ) : Boolean;
type
    TTimeRec = record
    CASE Integer OF
    0: ( ft: TFileTime );
    1: ( it: I64 );
    END;
var TR: TTimeRec;
begin
  TR.it := I64(
      Trunc( (DateTime - Date1601) * (24.0 * 3600 * 10000000) ) );
  Result := FileTimeToSystemTime( TR.ft, SystemTime );
end;
{$ENDIF}

end.
(*
/*

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

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

CONST STR :
    NATIVE_Date_time_import = "uses Windows, NATIVE_Date_time;"
    
    NATIVE_Date = @
    "var SD: TSystemTime;"
    "var d: Double;"
    "   FillChar(SD, Sizeof(SD), 0);"
    "   try "
    "       SD.wYear := X_Year;"
    "       SD.wMonth := X_Month;"
    "       SD.wDay := X_Day;"
    "       SystemTime2DateTime(SD, TDateTime(d));"
    "		Result := (d) * 24.0 * 3600000;"
    "   except {$IFNDEF NOERR} on E: Exception do {$ENDIF} begin"
    "          {$IFNDEF NOERR} Any_exception(E); {$ENDIF} end;"
    "   end;"
    
    NATIVE_Now = @
    "   Result := (Now) * 24.0 * 3600000;"
    
    NATIVE_UTC_now = @
    "var ST: TSystemTime;"
    "var d: Double;"
    "    GetSystemTime(ST);"
    "	 d := Result;"
    "    SystemTime2DateTime(ST, TDateTime(d));"
    "	 Result := (d) * 24.0 * 3600000;"
    
    NATIVE_Year = @
    "var ST: TSystemTime;"
    "   DateTime2SystemTime(X_D / 24.0 / 3600000, ST);"
    "   Result := ST.wYear;"
    
    NATIVE_Month = @
    "var ST: TSystemTime;"
    "   DateTime2SystemTime(X_D / 24.0 / 3600000, ST);"
    "   Result := ST.wMonth;"
    
    NATIVE_Day = @
    "var ST: TSystemTime;"
    "   DateTime2SystemTime(X_D / 24.0 / 3600000, ST);"
    "   Result := ST.wDay;"
    
    NATIVE_Week_day = @
    "var ST: TSystemTime;"
    "   DateTime2SystemTime(X_D / 24.0 / 3600000, ST);"
    "   Result := ST.wDayOfWeek;"
    
    NATIVE_Hour = @
    "var ST: TSystemTime;"
    "   DateTime2SystemTime(X_D / 24.0 / 3600000, ST);"
    "   Result := ST.wHour;"
    
    NATIVE_Minute = @
    "var ST: TSystemTime;"
    "   DateTime2SystemTime(X_D / 24.0 / 3600000, ST);"
    "   Result := ST.wMinute;"
    
    NATIVE_Second = @
    "var ST: TSystemTime;"
    "   DateTime2SystemTime(X_D / 24.0 / 3600000, ST);"
    "   Result := ST.wSecond;"
    
    NATIVE_Millisecond = @
    "var ST: TSystemTime;"
    "   DateTime2SystemTime(X_D / 24.0 / 3600000, ST);"
    "   Result := ST.wMilliseconds;"

    NATIVE_Day_of_year = @
    "var m: Integer;"
    "var ST: TSystemTime;"
    "var LY: Boolean;"
    "   DateTime2SystemTime(X_D / 24.0 / 3600000, ST);"
    "   LY := IsLeapYear(ST.wYear);"
    "   for m := 1 to ST.wMonth-1 do"
    "       inc(Result, MonthDays[LY, m]);"
    "   inc(RESULT, ST.wDay);"
    
    NATIVE_Days_in_month = @
    "var ST: TSystemTime;"
    "   DateTime2SystemTime(X_D / 24.0 / 3600000, ST);"
    "   Result := MonthDays[IsLeapYear(ST.wYear), St.wMonth];"
    
    NATIVE_Date_time_Str = @
    "    Result := DateTime2StrShort(X_D / 24.0 / 3600000);"
    .
         
END
*/
