| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864 |
- {
- Double Commander
- -------------------------------------------------------------------------
- Date and time functions.
- Copyright (C) 2009-2012 Przemysław Nagay ([email protected])
- Copyright (C) 2017-2025 Alexander Koblov ([email protected])
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- }
- unit DCDateTimeUtils;
- {$mode objfpc}
- {$H+}{$R-}{$Q-}
- interface
- uses
- Classes, SysUtils, DCBasicTypes
- {$IF DEFINED(MSWINDOWS)}
- , Windows
- {$ELSEIF DEFINED(UNIX)}
- , Unix, UnixUtil, DCUnix
- {$ENDIF}
- ;
- const
- DATE_TIME_NULL = TDateTime(2958466.0);
- function FileTimeToDateTime(FileTime : DCBasicTypes.TFileTime) : TDateTime;
- function FileTimeToDateTimeEx(FileTime : DCBasicTypes.TFileTimeEx) : TDateTime;
- function DateTimeToFileTime(DateTime : TDateTime) : DCBasicTypes.TFileTime;
- function DateTimeToFileTimeEx(DateTime : TDateTime) : DCBasicTypes.TFileTimeEx;
- function FileTimeToWinFileTime(FileTime : DCBasicTypes.TFileTime) : TWinFileTime;
- function FileTimeExToWinFileTime(FileTime : DCBasicTypes.TFileTimeEx) : TWinFileTime;
- function WinFileTimeToFileTimeEx(FileTime: TWinFileTime) : DCBasicTypes.TFileTimeEx;
- {en
- Converts system specific UTC time to local time.
- }
- function FileTimeToLocalFileTime(const FileTime: DCBasicTypes.TFileTime;
- out LocalFileTime: DCBasicTypes.TFileTime): LongBool;
- {en
- Converts system specific local time to UTC time.
- }
- function LocalFileTimeToFileTime(const LocalFileTime: DCBasicTypes.TFileTime;
- out FileTime: DCBasicTypes.TFileTime): LongBool;
- {en
- Converts Windows UTC file time to Windows local file time.
- @param(lpFileTime TWinFileTime structure containing the UTC-based file time)
- @param(lpLocalFileTime TWinFileTime structure to receive the converted local file time)
- @returns(The function returns @true if successful, @false otherwise)
- }
- function WinFileTimeToLocalFileTime(const FileTime: TWinFileTime;
- out LocalFileTime: TWinFileTime): LongBool;
- {en
- Converts Windows local file time to Windows UTC file time.
- @param(lpLocalFileTime TWinFileTime structure that specifies the local file time)
- @param(lpFileTime TWinFileTime structure to receive the converted UTC-based file time)
- @returns(The function returns @true if successful, @false otherwise)
- }
- function WinLocalFileTimeToFileTime(const LocalFileTime: TWinFileTime;
- out FileTime: TWinFileTime): LongBool;
- {en
- Converts Windows UTC file time to a file time in TDateTime format.
- @param(ft TWinFileTime structure containing the UTC-based file time)
- @returns(File time in TDateTime format)
- }
- function WinFileTimeToDateTime(ft : TWinFileTime) : TDateTime;
- {en
- Converts a file time in TDateTime format to Windows UTC file time.
- @param(dt File time in TDateTime format)
- @returns(Windows UTC-based file time)
- }
- function DateTimeToWinFileTime(dt : TDateTime) : TWinFileTime;
- function DosFileTimeToDateTime(const DosTime: TDosFileTime): TDateTime;
- function DateTimeToDosFileTime(const DateTime: TDateTime): TDosFileTime;
- {$IFDEF MSWINDOWS}
- function VariantTimeToDateTime(VarTime: Double): TDateTime;
- function WinFileTimeToDateTime(ft : Windows.FILETIME) : TDateTime; inline; overload;
- function WinToDosTime(const WinTime: Windows.FILETIME; var DosTime: TDosFileTime): LongBool; overload;
- function DosToWinTime(const DosTime: TDosFileTime; var WinTime: Windows.FILETIME): LongBool; overload;
- function WinToDosTime(const WinTime: TWinFileTime; var DosTime: TDosFileTime): LongBool;
- function DosToWinTime(const DosTime: TDosFileTime; var WinTime: TWinFileTime): LongBool;
- {$ENDIF}
- function UnixFileTimeToDateTime(UnixTime: TUnixFileTime) : TDateTime;
- {$IFDEF UNIX}
- function UnixFileTimeToDateTimeEx(UnixTime: DCBasicTypes.TFileTimeEx) : TDateTime;
- {$ENDIF}
- function DateTimeToUnixFileTime(DateTime: TDateTime) : TUnixFileTime;
- function DateTimeToUnixFileTimeEx(DateTime: TDateTime) : DCBasicTypes.TFileTimeEx;
- function UnixFileTimeToFileTime(UnixTime: TUnixFileTime): DCBasicTypes.TFileTime;
- function UnixFileTimeToDosTime(UnixTime: TUnixFileTime): TDosFileTime;
- function DosTimeToUnixFileTime(DosTime: TDosFileTime): TUnixFileTime;
- function UnixFileTimeToWinTime(UnixTime: TUnixFileTime): TWinFileTime;
- function WinFileTimeToUnixTime(WinTime: TWinFileTime) : TUnixFileTime;
- function WinFileTimeToDosTime(FileTime: TWinFileTime): TDosFileTime;
- function DosTimeToWinFileTime(FileTime: TDosFileTime): TWinFileTime;
- function WcxFileTimeToFileTime(WcxTime: LongInt): DCBasicTypes.TFileTime; inline;
- function FileTimeToWcxFileTime(FileTime: DCBasicTypes.TFileTime): LongInt; inline;
- function WcxFileTimeToDateTime(WcxTime: LongInt): TDateTime;
- function UnixFileTimeToWcxTime(UnixTime: TUnixFileTime): LongInt;
- function GetTimeZoneBias: LongInt;
- {en
- Converts a month short name to month number.
- @param(ShortMonthName Month short name)
- @param(Default Default month number)
- @returns(Month number)
- }
- function MonthToNumberDef(const ShortMonthName: String; Default: Word): Word;
- {en
- Converts a year short record to year long record if need (10 -> 2010).
- @param(Year Year short record)
- @returns(Year long record)
- }
- function YearShortToLong(Year: Word): Word;
- function TwelveToTwentyFour(Hour: Word; Modifier: AnsiString): Word;
- function FileTimeCompare(SourceTime, TargetTime: TDateTime; NtfsShift: Boolean): Integer;
- type
- EDateOutOfRange = class(EConvertError)
- private
- FDateTime: TDateTime;
- public
- constructor Create(ADateTime: TDateTime);
- property DateTime: TDateTime read FDateTime;
- end;
- implementation
- uses
- DateUtils;
- const
- UnixWinEpoch = TWinFileTime($019DB1DED53E8000); // Unix epoch start
- MinWinUnixSec = (0 - TUnixFileTime(UnixWinEpoch div 10000000 - 1));
- MaxWinUnixSec = TUnixFileTime(High(TWinFileTime) div 10000000 - 1);
- const { Short names of months. }
- ShortMonthNames: TMonthNameArray = ('Jan','Feb','Mar','Apr','May','Jun',
- 'Jul','Aug','Sep','Oct','Nov','Dec');
- {$IF DEFINED(MSWINDOWS)}
- var
- WinTimeZoneBias: LongInt;
- TzSpecificLocalTimeToSystemTime: function(lpTimeZoneInformation: PTimeZoneInformation;
- lpLocalTime, lpUniversalTime: PSystemtime): BOOL; stdcall;
- {$ENDIF}
- function AdjustUnixFileTime(const FileTime: DCBasicTypes.TFileTime;
- out AdjustedFileTime: DCBasicTypes.TFileTime;
- AdjustValue: Int64): Boolean;
- begin
- if AdjustValue < 0 then
- begin
- if FileTime < DCBasicTypes.TFileTime(-AdjustValue) then
- begin
- AdjustedFileTime := 0;
- Result := False;
- end
- else
- begin
- AdjustedFileTime := FileTime - DCBasicTypes.TFileTime(-AdjustValue);
- Result := True;
- end;
- end
- else
- begin
- if High(FileTime) - FileTime < DCBasicTypes.TFileTime(AdjustValue) then
- begin
- AdjustedFileTime := High(FileTime);
- Result := False;
- end
- else
- begin
- AdjustedFileTime := FileTime + DCBasicTypes.TFileTime(AdjustValue);
- Result := True;
- end;
- end;
- end;
- function AdjustWinFileTime(const FileTime: TWinFileTime;
- out AdjustedFileTime: TWinFileTime;
- AdjustValue: Int64): Boolean;
- begin
- if AdjustValue < 0 then
- begin
- if FileTime < DCBasicTypes.TWinFileTime(-AdjustValue) then
- begin
- AdjustedFileTime := 0;
- Result := False;
- end
- else
- begin
- AdjustedFileTime := FileTime - DCBasicTypes.TWinFileTime(-AdjustValue);
- Result := True;
- end;
- end
- else
- begin
- if High(FileTime) - FileTime < DCBasicTypes.TWinFileTime(AdjustValue) then
- begin
- AdjustedFileTime := High(FileTime);
- Result := False;
- end
- else
- begin
- AdjustedFileTime := FileTime + DCBasicTypes.TWinFileTime(AdjustValue);
- Result := True;
- end;
- end;
- end;
- function FileTimeToDateTime(FileTime : DCBasicTypes.TFileTime) : TDateTime; inline;
- {$IF DEFINED(MSWINDOWS)}
- begin
- Result := WinFileTimeToDateTime(FileTime);
- end;
- {$ELSEIF DEFINED(UNIX)}
- begin
- Result := UnixFileTimeToDateTime(FileTime);
- end;
- {$ELSE}
- begin
- Result := 0;
- end;
- {$ENDIF}
- function FileTimeToDateTimeEx(FileTime : DCBasicTypes.TFileTimeEx) : TDateTime;
- {$IF DEFINED(MSWINDOWS)}
- begin
- Result := WinFileTimeToDateTime(FileTime);
- end;
- {$ELSEIF DEFINED(UNIX)}
- begin
- Result := UnixFileTimeToDateTimeEx(FileTime);
- end;
- {$ELSE}
- begin
- Result := 0;
- end;
- {$ENDIF}
- function DateTimeToFileTime(DateTime : TDateTime) : DCBasicTypes.TFileTime; inline;
- {$IF DEFINED(MSWINDOWS)}
- begin
- Result := DateTimeToWinFileTime(DateTime);
- end;
- {$ELSEIF DEFINED(UNIX)}
- begin
- Result := DateTimeToUnixFileTime(DateTime);
- end;
- {$ELSE}
- begin
- Result := 0;
- end;
- {$ENDIF}
- function DateTimeToFileTimeEx(DateTime : TDateTime) : DCBasicTypes.TFileTimeEx; inline;
- {$IF DEFINED(MSWINDOWS)}
- begin
- Result := DateTimeToWinFileTime(DateTime);
- end;
- {$ELSEIF DEFINED(UNIX)}
- begin
- Result := DateTimeToUnixFileTimeEx(DateTime);
- end;
- {$ELSE}
- begin
- Result := 0;
- end;
- {$ENDIF}
- function FileTimeToWinFileTime(FileTime: DCBasicTypes.TFileTime): TWinFileTime; inline;
- {$IF DEFINED(MSWINDOWS)}
- begin
- Result:= TWinFileTime(FileTime)
- end;
- {$ELSEIF DEFINED(UNIX)}
- begin
- Result:= UnixFileTimeToWinTime(TUnixFileTime(FileTime));
- end;
- {$ENDIF}
- function FileTimeExToWinFileTime(FileTime: DCBasicTypes.TFileTimeEx): TWinFileTime;
- {$IF DEFINED(MSWINDOWS)}
- begin
- Result:= TWinFileTime(FileTime)
- end;
- {$ELSEIF DEFINED(UNIX)}
- begin
- if (FileTime.Sec > MaxWinUnixSec) then
- Result:= High(TWinFileTime)
- else if (FileTime.Sec < MinWinUnixSec) then
- Result:= Low(TWinFileTime)
- else begin
- Result:= UnixWinEpoch + FileTime.sec * 10000000 + FileTime.nanosec div 100;
- end;
- end;
- {$ENDIF}
- function WinFileTimeToFileTimeEx(FileTime: TWinFileTime): DCBasicTypes.TFileTimeEx;
- {$IF DEFINED(MSWINDOWS)}
- begin
- Result := TFileTimeEx(FileTime);
- end;
- {$ELSEIF DEFINED(UNIX)}
- begin
- if (FileTime >= UnixWinEpoch) then
- begin
- Result.Sec:= Int64((FileTime - UnixWinEpoch) div 10000000);
- Result.NanoSec:= Int64((FileTime - UnixWinEpoch) mod 10000000) * 100;
- end
- else begin
- Result.Sec:= (Int64(FileTime) - Int64(UnixWinEpoch)) div 10000000;
- if (Result.Sec = 0) then
- Result.NanoSec:= 0
- else begin
- Result.NanoSec:= (Int64(UnixWinEpoch - FileTime) mod 10000000) * 100;
- if (Result.NanoSec > 0) then Result.NanoSec:= 1000000000 - Result.NanoSec;
- end;
- end;
- end;
- {$ENDIF}
- function FileTimeToLocalFileTime(const FileTime: DCBasicTypes.TFileTime;
- out LocalFileTime: DCBasicTypes.TFileTime): LongBool;
- {$IFDEF MSWINDOWS}
- begin
- Result := Windows.FileTimeToLocalFileTime(@Windows.FILETIME(FileTime), @Windows.FILETIME(LocalFileTime));
- end;
- {$ELSE}
- begin
- Result := AdjustUnixFileTime(FileTime, LocalFileTime, Tzseconds);
- end;
- {$ENDIF}
- function LocalFileTimeToFileTime(const LocalFileTime: DCBasicTypes.TFileTime;
- out FileTime: DCBasicTypes.TFileTime): LongBool;
- {$IFDEF MSWINDOWS}
- begin
- Result := Windows.LocalFileTimeToFileTime(@Windows.FILETIME(LocalFileTime), @Windows.FILETIME(FileTime));
- end;
- {$ELSE}
- begin
- Result := AdjustUnixFileTime(LocalFileTime, FileTime, -Tzseconds);
- end;
- {$ENDIF}
- function WinFileTimeToLocalFileTime(const FileTime: TWinFileTime;
- out LocalFileTime: TWinFileTime): LongBool;
- {$IFDEF MSWINDOWS}
- begin
- Result := Windows.FileTimeToLocalFileTime(@Windows.FILETIME(FileTime), @Windows.FILETIME(LocalFileTime));
- end;
- {$ELSE}
- begin
- Result := AdjustWinFileTime(FileTime, LocalFileTime, 10000000 * Int64(TZSeconds));
- end;
- {$ENDIF}
- function WinLocalFileTimeToFileTime(const LocalFileTime: TWinFileTime;
- out FileTime: TWinFileTime): LongBool;
- {$IFDEF MSWINDOWS}
- begin
- Result := Windows.LocalFileTimeToFileTime(@Windows.FILETIME(LocalFileTime), @Windows.FILETIME(FileTime));
- end;
- {$ELSE}
- begin
- Result := AdjustWinFileTime(LocalFileTime, FileTime, -10000000 * Int64(TZSeconds));
- end;
- {$ENDIF}
- function WinFileTimeToDateTime(ft : TWinFileTime) : TDateTime;
- {$IF DEFINED(MSWINDOWS)}
- var
- lpUniversalTime, lpLocalTime: TSystemTime;
- begin
- if (Win32MajorVersion > 5) then
- begin
- FileTimeToSystemTime(@ft, @lpUniversalTime);
- SystemTimeToTzSpecificLocalTime(nil, @lpUniversalTime, @lpLocalTime);
- Result := SystemTimeToDateTime(lpLocalTime);
- end
- else
- begin
- WinFileTimeToLocalFileTime(ft,ft);
- Result := (ft / 864000000000.0) - 109205.0;
- end;
- end;
- {$ELSE}
- begin
- Result := FileTimeToDateTimeEx(WinFileTimeToFileTimeEx(ft));
- end;
- {$ENDIF}
- function DateTimeToWinFileTime(dt : TDateTime) : TWinFileTime;
- {$IF DEFINED(MSWINDOWS)}
- var
- lpUniversalTime, lpLocalTime: TSystemTime;
- begin
- if (Win32MajorVersion > 5) then
- begin
- DateTimeToSystemTime(dt, lpLocalTime);
- TzSpecificLocalTimeToSystemTime(nil, @lpLocalTime, @lpUniversalTime);
- SystemTimeToFileTime(@lpUniversalTime, @Result);
- end
- else
- begin
- Result := Round((Extended(dt) + 109205.0) * 864000000000.0);
- WinLocalFileTimeToFileTime(Result, Result);
- end;
- end;
- {$ELSE}
- begin
- Result := FileTimeExToWinFileTime(DateTimeToFileTimeEx(dt));
- end;
- {$ENDIF}
- function DosFileTimeToDateTime(const DosTime: TDosFileTime): TDateTime;
- var
- Yr, Mo, Dy : Word;
- Hr, Mn, S : Word;
- FileDate, FileTime : Word;
- begin
- FileDate := LongRec(DosTime).Hi;
- FileTime := LongRec(DosTime).Lo;
- Yr := FileDate shr 9 + 1980;
- Mo := FileDate shr 5 and 15;
- if Mo < 1 then Mo := 1;
- if Mo > 12 then Mo := 12;
- Dy := FileDate and 31;
- if Dy < 1 then Dy := 1;
- if Dy > DaysInAMonth(Yr, Mo) then
- Dy := DaysInAMonth(Yr, Mo);
- Hr := FileTime shr 11;
- if Hr > 23 then Hr := 23;
- Mn := FileTime shr 5 and 63;
- if Mn > 59 then Mn := 59;
- S := FileTime and 31 shl 1;
- if S > 59 then S := 59;
- Result := ComposeDateTime(EncodeDate(Yr, Mo, Dy),
- EncodeTime(Hr, Mn, S, 0));
- end;
- function DateTimeToDosFileTime(const DateTime: TDateTime): TDosFileTime;
- var
- Yr, Mo, Dy : Word;
- Hr, Mn, S, MS: Word;
- begin
- DecodeDate(DateTime, Yr, Mo, Dy);
- DecodeTime(DateTime, Hr, Mn, S, MS);
- // Outside DOS file date year range
- if (Yr < 1980) then
- Yr := 1980
- else if (Yr > 2107) then
- begin
- Yr := 2107;
- end;
- LongRec(Result).Lo := (S shr 1) or (Mn shl 5) or (Hr shl 11);
- LongRec(Result).Hi := Dy or (Mo shl 5) or (Word(Yr - 1980) shl 9);
- end;
- {$IFDEF MSWINDOWS}
- function VariantTimeToDateTime(VarTime: Double): TDateTime;
- var
- lpUniversalTime, lpLocalTime: TSystemTime;
- begin
- if (Win32MajorVersion > 5) then
- begin
- DateTimeToSystemTime(VarTime, lpUniversalTime);
- SystemTimeToTzSpecificLocalTime(nil, @lpUniversalTime, @lpLocalTime);
- Result := SystemTimeToDateTime(lpLocalTime);
- end
- else begin
- Result := IncMinute(VarTime, -WinTimeZoneBias);
- end;
- end;
- function WinFileTimeToDateTime(ft : Windows.FILETIME) : TDateTime;
- begin
- Result := WinFileTimeToDateTime(TWinFileTime(ft));
- end;
- function WinToDosTime(const WinTime: Windows.FILETIME; var DosTime: TDosFileTime): LongBool;
- var
- lft : Windows.TFILETIME;
- begin
- Result:= Windows.FileTimeToLocalFileTime(@Windows.FILETIME(WinTime), @lft) and
- Windows.FileTimeToDosDateTime(@lft, @LongRec(Dostime).Hi, @LongRec(DosTime).Lo);
- end;
- function DosToWinTime(const DosTime: TDosFileTime; var WinTime: Windows.FILETIME): LongBool;
- var
- lft : Windows.TFILETIME;
- begin
- Result := Windows.DosDateTimeToFileTime(LongRec(DosTime).Hi, LongRec(DosTime).Lo, @lft) and
- Windows.LocalFileTimeToFileTime(@lft, @Windows.FILETIME(WinTime));
- end;
- function WinToDosTime(const WinTime: TWinFileTime; var DosTime: TDosFileTime): LongBool;
- var
- lft : Windows.TFILETIME;
- begin
- Result:= Windows.FileTimeToLocalFileTime(@Windows.FILETIME(WinTime), @lft) and
- Windows.FileTimeToDosDateTime(@lft, @LongRec(Dostime).Hi, @LongRec(DosTime).Lo);
- end;
- function DosToWinTime(const DosTime: TDosFileTime; var WinTime: TWinFileTime): LongBool;
- var
- lft : Windows.TFILETIME;
- begin
- Result := Windows.DosDateTimeToFileTime(LongRec(DosTime).Hi, LongRec(DosTime).Lo, @lft) and
- Windows.LocalFileTimeToFileTime(@lft, @Windows.FILETIME(WinTime));
- end;
- {$ENDIF}
- {$IF DEFINED(UNIX)}
- function UnixFileTimeToDateTime(UnixTime: TUnixFileTime) : TDateTime;
- var
- filetime: DCBasicTypes.TFileTimeEx;
- begin
- filetime:= TFileTimeEx.create(UnixTime);
- Result:= UnixFileTimeToDateTimeEx(filetime);
- end;
- function UnixFileTimeToDateTimeEx(UnixTime: DCBasicTypes.TFileTimeEx) : TDateTime;
- var
- ATime: TTimeStruct;
- Milliseconds: Word;
- begin
- if (fpLocalTime(@UnixTime.sec, @ATime) = nil) then
- Exit(UnixEpoch);
- ATime.tm_mon += 1;
- ATime.tm_year += 1900;
- if (ATime.tm_year < 1) then
- ATime.tm_year := 1
- else if (ATime.tm_year > 9999) then
- ATime.tm_year := 9999;
- if ATime.tm_sec > 59 then
- ATime.tm_sec := 59;
- if (UnixTime.nanosec > 999000000) then
- Milliseconds := 999
- else begin
- Milliseconds := Round( Extended(UnixTime.nanosec) / (1000.0 * 1000.0) );
- end;
- Result := ComposeDateTime(EncodeDate(ATime.tm_year, ATime.tm_mon, ATime.tm_mday),
- EncodeTime(ATime.tm_hour, ATime.tm_min, ATime.tm_sec, milliseconds));
- end;
- {$ELSE}
- function UnixFileTimeToDateTime(UnixTime: TUnixFileTime) : TDateTime;
- var
- WinFileTime: TWinFileTime;
- begin
- WinFileTime:= UnixFileTimeToWinTime(UnixTime);
- Result:= WinFileTimeToDateTime(WinFileTime);
- end;
- {$ENDIF}
- function DateTimeToUnixFileTime(DateTime : TDateTime): TUnixFileTime;
- {$IF DEFINED(UNIX)}
- var
- AUnixTime: TTime;
- ATime: TTimeStruct;
- Year, Month, Day: Word;
- Hour, Minute, Second, MilliSecond: Word;
- begin
- DecodeDate(DateTime, Year, Month, Day);
- DecodeTime(DateTime, Hour, Minute, Second, MilliSecond);
- ATime.tm_isdst:= -1;
- ATime.tm_year:= Year - 1900;
- ATime.tm_mon:= Month - 1;
- ATime.tm_mday:= Day;
- ATime.tm_hour:= Hour;
- ATime.tm_min:= Minute;
- ATime.tm_sec:= Second;
- AUnixTime:= fpMkTime(@ATime);
- if (AUnixTime = -1) then
- Result:= 0
- else begin
- Result:= TUnixFileTime(AUnixTime);
- end;
- end;
- {$ELSE}
- var
- WinFileTime: TWinFileTime;
- begin
- WinFileTime:= DateTimeToWinFileTime(DateTime);
- Result:= WinFileTimeToUnixTime(WinFileTime);
- end;
- {$ENDIF}
- function DateTimeToUnixFileTimeEx(DateTime : TDateTime): DCBasicTypes.TFileTimeEx;
- {$IF DEFINED(UNIX)}
- var
- AUnixTime: TTime;
- ATime: TTimeStruct;
- Year, Month, Day: Word;
- Hour, Minute, Second, MilliSecond: Word;
- begin
- if DateTime < UnixEpoch then
- raise EDateOutOfRange.Create(DateTime);
- DecodeDate(DateTime, Year, Month, Day);
- DecodeTime(DateTime, Hour, Minute, Second, MilliSecond);
- ATime.tm_isdst:= -1;
- ATime.tm_year:= Year - 1900;
- ATime.tm_mon:= Month - 1;
- ATime.tm_mday:= Day;
- ATime.tm_hour:= Hour;
- ATime.tm_min:= Minute;
- ATime.tm_sec:= Second;
- AUnixTime:= fpMkTime(@ATime);
- if (AUnixTime = -1) then
- Result:= TFileTimeExNull
- else begin
- Result:= TFileTimeEx.Create(AUnixTime, MilliSecond * 1000 * 1000);
- end;
- end;
- {$ELSE}
- var
- WinFileTime: TWinFileTime;
- begin
- WinFileTime:= DateTimeToWinFileTime(DateTime);
- Result:= WinFileTimeToUnixTime(WinFileTime);
- end;
- {$ENDIF}
- function UnixFileTimeToFileTime(UnixTime: TUnixFileTime): DCBasicTypes.TFileTime; inline;
- begin
- {$IF DEFINED(MSWINDOWS)}
- Result:= UnixFileTimeToWinTime(UnixTime);
- {$ELSE}
- Result:= UnixTime;
- {$ENDIF}
- end;
- function UnixFileTimeToDosTime(UnixTime: TUnixFileTime): TDosFileTime;
- begin
- Result := DateTimeToDosFileTime(UnixFileTimeToDateTime(UnixTime));
- end;
- function DosTimeToUnixFileTime(DosTime: TDosFileTime): TUnixFileTime;
- begin
- Result:= DateTimeToUnixFileTime(DosFileTimeToDateTime(DosTime));
- end;
- function UnixFileTimeToWinTime(UnixTime: TUnixFileTime): TWinFileTime;
- var
- WinFileTime: TWinFileTime;
- begin
- WinFileTime := UnixWinEpoch;
- if not AdjustWinFileTime(WinFileTime, Result, 10000000 * Int64(UnixTime)) then
- Result := WinFileTime;
- end;
- function WinFileTimeToUnixTime(WinTime: TWinFileTime): TUnixFileTime;
- begin
- if (WinTime < UnixWinEpoch) then
- Result:= 0
- else
- Result:= TUnixFileTime((WinTime - UnixWinEpoch) div 10000000);
- end;
- function WinFileTimeToDosTime(FileTime: TWinFileTime): TDosFileTime;
- begin
- Result := DateTimeToDosFileTime(WinFileTimeToDateTime(FileTime));
- end;
- function DosTimeToWinFileTime(FileTime: TDosFileTime): TWinFileTime;
- begin
- Result := DateTimeToWinFileTime(DosFileTimeToDateTime(FileTime));
- end;
- function WcxFileTimeToFileTime(WcxTime: LongInt): DCBasicTypes.TFileTime;
- begin
- {$IF DEFINED(MSWINDOWS)}
- DosToWinTime(TDosFileTime(WcxTime), Result);
- {$ELSE}
- Result := TFileTime(WcxTime);
- {$ENDIF}
- end;
- function FileTimeToWcxFileTime(FileTime: DCBasicTypes.TFileTime): LongInt;
- begin
- {$IF DEFINED(MSWINDOWS)}
- WinToDosTime(FileTime, Result);
- {$ELSE}
- Result := LongInt(FileTime);
- {$ENDIF}
- end;
- function WcxFileTimeToDateTime(WcxTime: LongInt): TDateTime;
- begin
- {$IF DEFINED(MSWINDOWS)}
- Result := DosFileTimeToDateTime(WcxTime);
- {$ELSEIF DEFINED(UNIX)}
- {$PUSH}{$R-}
- Result := FileTimeToDateTime(WcxTime);
- {$POP}
- {$ELSE}
- Result := 0;
- {$ENDIF}
- end;
- function UnixFileTimeToWcxTime(UnixTime: TUnixFileTime): LongInt;
- begin
- {$IF DEFINED(MSWINDOWS)}
- Result := UnixFileTimeToDosTime(UnixTime);
- {$ELSEIF DEFINED(UNIX)}
- {$PUSH}{$R-}
- Result := UnixTime;
- {$POP}
- {$ELSE}
- Result := 0;
- {$ENDIF}
- end;
- function GetTimeZoneBias: LongInt;
- begin
- {$IF DEFINED(MSWINDOWS)}
- Result := WinTimeZoneBias;
- {$ELSEIF DEFINED(UNIX)}
- Result := -Tzseconds div 60;
- {$ELSE}
- Result := 0;
- {$ENDIF}
- end;
- function MonthToNumberDef(const ShortMonthName: String; Default: Word): Word;
- var
- I: Word;
- begin
- Result:= Default;
- if ShortMonthName = EmptyStr then Exit;
- for I:= 1 to 12 do
- if SameText(ShortMonthName, ShortMonthNames[I]) then
- Exit(I);
- end;
- function YearShortToLong(Year: Word): Word;
- begin
- Result:= Year;
- if (Year < 100) then
- begin
- if (Year < 80) then
- Result:= Year + 2000
- else
- Result:= Year + 1900;
- end;
- end;
- function TwelveToTwentyFour(Hour: Word; Modifier: AnsiString): Word;
- begin
- Result:= Hour;
- if Length(Modifier) > 0 then
- begin
- case LowerCase(Modifier[1]) of
- 'a':
- begin
- if (Hour = 12) then
- Result:= 0;
- end;
- 'p':
- begin
- if (Hour < 12) then
- Result:= Hour + 12;
- end;
- end;
- end;
- end;
- function FileTimeCompare(SourceTime, TargetTime: TDateTime; NtfsShift: Boolean): Integer;
- const
- TimeDiff = 3100 / MSecsPerDay;
- NtfsDiff:TDateTime = (1/HoursPerDay);
- var
- FileTimeDiff,
- NtfsTimeDiff: TDateTime;
- begin
- FileTimeDiff:= SourceTime - TargetTime;
- if NtfsShift then
- begin
- NtfsTimeDiff:= FileTimeDiff - NtfsDiff;
- if (NtfsTimeDiff > -TimeDiff) and (NtfsTimeDiff < TimeDiff) then
- Exit(0);
- NtfsTimeDiff:= FileTimeDiff + NtfsDiff;
- if (NtfsTimeDiff > -TimeDiff) and (NtfsTimeDiff < TimeDiff) then
- Exit(0);
- end;
- if (FileTimeDiff > -TimeDiff) and (FileTimeDiff < TimeDiff) then
- Result:= 0
- else if FileTimeDiff > 0 then
- Result:= +1
- else if FileTimeDiff < 0 then
- Result:= -1;
- end;
- { EDateOutOfRange }
- constructor EDateOutOfRange.Create(ADateTime: TDateTime);
- begin
- inherited Create(EmptyStr);
- FDateTime := ADateTime;
- end;
- {$IF DEFINED(MSWINDOWS)}
- initialization
- WinTimeZoneBias := GetLocalTimeOffset;
- if (Win32MajorVersion > 5) then
- begin
- Pointer(TzSpecificLocalTimeToSystemTime):= GetProcAddress(GetModuleHandle(Kernel32),
- 'TzSpecificLocalTimeToSystemTime');
- end;
- {$ENDIF}
- end.
|