unit DateTime; interface uses Windows; const SecondsPerDay = 24*60*60; // Days between 1/1/0001 and 12/31/1899 DateDelta = 693594; // Days between TDateTime basis (12/31/1899) and Unix time_t basis (1/1/1970) UnixDateDelta = 25569; // Days between Unix time_t basis (1/1/1970) and Windows timestamp (1/1/1601) WinDateDelta = 134774; // function IsLeapYear(Year:word):Boolean; function EncodeTime(Hour, Minute, Sec: cardinal):TDateTime; function EncodeDate(Year, Month , Day: cardinal):TDateTime; function Timestamp(Year,Month,Day:cardinal;Hour:cardinal=0;Minute:cardinal=0;Sec:cardinal=0):dword; function GetCurrentTimestamp:DWord; procedure UnixTimeToFileTime(ts:int_ptr; var pft:TFILETIME); function FileTimeToUnixTime(const pft: TFILETIME):int_ptr; function TimeStampToLocalTimeStamp(ts:int_ptr):int_ptr; function TimestampToDateTime(ts:int_ptr):TDateTime; function TimestampToSystemTime(Time:DWord; var ST:TSystemTime):PSystemTime; function DateTimeToStr(Time:Dword; Format:pWideChar=nil):pWideChar; function DateToStr (Time:Dword; Format:pWideChar=nil):pWideChar; function TimeToStr (Time:Dword; Format:pWideChar=nil):pWideChar; implementation uses common; type PDayTable = ^TDayTable; TDayTable = array [0..11] of byte; 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 EncodeTime(Hour, Minute, Sec: cardinal): TDateTime; begin result := (Hour*3600 + Minute*60 + Sec) / SecondsPerDay; end; function EncodeDate(Year, Month, Day: cardinal):TDateTime; var DayTable: PDayTable; begin DayTable := @MonthDays[IsLeapYear(Year)]; dec(Month); while Month>0 do begin dec(Month); inc(Day,DayTable^[Month]); end; dec(Year); result := Year * 365 + Year div 4 - Year div 100 + Year div 400 + Day - DateDelta; end; function Timestamp(Year,Month,Day:cardinal;Hour:cardinal=0;Minute:cardinal=0;Sec:cardinal=0):dword; var t:tDateTime; begin t := EncodeDate(Year, Month, Day); if t >= 0 then t := t + EncodeTime(Hour, Minute, Sec) else t := t - EncodeTime(Hour, Minute, Sec); result:=Round((t - UnixDateDelta) * SecondsPerDay); end; function GetCurrentTimestamp:dword; var st:tSystemTime; begin GetSystemTime(st); result:=Timestamp(st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond); end; procedure UnixTimeToFileTime(ts:int_ptr; var pft:TFILETIME); var ll:uint64; begin ll := (int64(WinDateDelta)*SecondsPerDay + ts) * 10000000; pft.dwLowDateTime := dword(ll); pft.dwHighDateTime := ll shr 32; end; function FileTimeToUnixTime(const pft: TFILETIME):int_ptr; var ll:uint64; begin ll := (uint64(pft.dwHighDateTime) shl 32) or pft.dwLowDateTime; ll := (ll div 10000000) - int64(WinDateDelta)*SecondsPerDay; result := int_ptr(ll); end; function TimeStampToLocalTimeStamp(ts:int_ptr):int_ptr; var ft,lft:TFileTime; begin UnixTimeToFileTime(ts,ft); FileTimeToLocalFileTime(ft, lft); result:=FileTimeToUnixTime(lft); end; function TimestampToDateTime(ts:int_ptr):TDateTime; begin Result := UnixDateDelta + TimeStampToLocalTimeStamp(ts) / SecondsPerDay; end; function TimestampToSystemTime(Time:DWord; var ST:TSystemTime):PSystemTime; var aft,lft:TFILETIME; begin UnixTimeToFileTime(Time,aft); FileTimeToLocalFileTime(aft, lft); FileTimeToSystemTime(lft,ST); result:=@ST; end; function DateTimeToStr(Time:Dword; Format:pWideChar=nil):pWideChar; var buf:array [0..300] of WideChar; ST: TSystemTime; pc:pWideChar; begin TimestampToSystemTime(Time,ST); GetDateFormatW(LOCALE_USER_DEFAULT,0,@ST,Format,@buf,300); if Format<>nil then GetTimeFormatW(LOCALE_USER_DEFAULT,0,@ST,@buf,@buf,300) else begin pc:=StrEndW(@buf); pc^:=' '; inc(pc); GetTimeFormatW(LOCALE_USER_DEFAULT,0,@ST,nil,pc,300-(pc-pWideChar(@buf))) end; StrDupW(result,buf); end; function DateToStr(Time:Dword; Format:pWideChar=nil):pWideChar; var buf:array [0..300] of WideChar; ST: TSystemTime; begin TimestampToSystemTime(Time,ST); GetDateFormatW(LOCALE_USER_DEFAULT,0,@ST,Format,@buf,300); StrDupW(result,buf); end; function TimeToStr(Time:Dword; Format:pWideChar=nil):pWideChar; var buf:array [0..300] of WideChar; ST: TSystemTime; begin TimestampToSystemTime(Time,ST); GetTimeFormatW(LOCALE_USER_DEFAULT,0,@ST,Format,@buf,300); StrDupW(result,buf); end; end.