mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
UPD: DCDateTimeUtils - better time zone support (Unix)
This commit is contained in:
parent
5275b991f4
commit
4ff6ff14dd
2 changed files with 43 additions and 51 deletions
|
|
@ -62,10 +62,17 @@ const
|
|||
implementation
|
||||
|
||||
{$IF not DEFINED(MSWINDOWS)}
|
||||
constructor TFileTimeEx.create( aSec:int64; aNanosec:int64 );
|
||||
constructor TFileTimeEx.Create(aSec: Int64; aNanosec: Int64);
|
||||
begin
|
||||
self.sec:= aSec;
|
||||
self.nanosec:= aNanosec;
|
||||
Self.sec:= aSec;
|
||||
Self.nanosec:= aNanosec;
|
||||
|
||||
if Self.nanosec < 0 then
|
||||
Self.nanosec := 0
|
||||
else if Self.nanosec > 999999999 then
|
||||
begin
|
||||
Self.nanosec := 999999999;
|
||||
end;
|
||||
end;
|
||||
|
||||
class operator TFileTimeEx.=(l,r : TFileTimeEx): Boolean;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
Date and time functions.
|
||||
|
||||
Copyright (C) 2009-2012 Przemysław Nagay (cobines@gmail.com)
|
||||
Copyright (C) 2017-2024 Alexander Koblov (alexx2000@mail.ru)
|
||||
Copyright (C) 2017-2025 Alexander Koblov (alexx2000@mail.ru)
|
||||
|
||||
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
|
||||
|
|
@ -44,6 +44,7 @@ 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
|
||||
|
|
@ -147,6 +148,8 @@ uses
|
|||
|
||||
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',
|
||||
|
|
@ -283,7 +286,7 @@ begin
|
|||
end;
|
||||
{$ENDIF}
|
||||
|
||||
function FileTimeToWinFileTime(FileTime: DCBasicTypes.TFileTime): TWinFileTime;
|
||||
function FileTimeToWinFileTime(FileTime: DCBasicTypes.TFileTime): TWinFileTime; inline;
|
||||
{$IF DEFINED(MSWINDOWS)}
|
||||
begin
|
||||
Result:= TWinFileTime(FileTime)
|
||||
|
|
@ -294,6 +297,23 @@ begin
|
|||
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
|
||||
|
|
@ -358,9 +378,7 @@ function WinFileTimeToDateTime(ft : TWinFileTime) : TDateTime;
|
|||
{$IF DEFINED(MSWINDOWS)}
|
||||
var
|
||||
lpUniversalTime, lpLocalTime: TSystemTime;
|
||||
{$ENDIF}
|
||||
begin
|
||||
{$IF DEFINED(MSWINDOWS)}
|
||||
if (Win32MajorVersion > 5) then
|
||||
begin
|
||||
FileTimeToSystemTime(@ft, @lpUniversalTime);
|
||||
|
|
@ -368,20 +386,22 @@ begin
|
|||
Result := SystemTimeToDateTime(lpLocalTime);
|
||||
end
|
||||
else
|
||||
{$ENDIF}
|
||||
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;
|
||||
{$ENDIF}
|
||||
begin
|
||||
{$IF DEFINED(MSWINDOWS)}
|
||||
if (Win32MajorVersion > 5) then
|
||||
begin
|
||||
DateTimeToSystemTime(dt, lpLocalTime);
|
||||
|
|
@ -389,12 +409,16 @@ begin
|
|||
SystemTimeToFileTime(@lpUniversalTime, @Result);
|
||||
end
|
||||
else
|
||||
{$ENDIF}
|
||||
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
|
||||
|
|
@ -499,43 +523,6 @@ end;
|
|||
|
||||
|
||||
{$IF DEFINED(UNIX)}
|
||||
procedure NormalizeFileTime(var UnixTime: DCBasicTypes.TFileTimeEx);
|
||||
const
|
||||
NSecsPerSec = 1000000000;
|
||||
begin
|
||||
while UnixTime.nanosec <= -NSecsPerSec do
|
||||
begin
|
||||
if (UnixTime.sec = Low(Int64)) then
|
||||
begin
|
||||
UnixTime.nanosec:= 0;
|
||||
Exit;
|
||||
end;
|
||||
Dec(UnixTime.sec);
|
||||
Inc(UnixTime.nanosec, NSecsPerSec);
|
||||
end;
|
||||
while UnixTime.nanosec >= NSecsPerSec do
|
||||
begin
|
||||
if (UnixTime.sec = High(Int64)) then
|
||||
begin
|
||||
UnixTime.nanosec:= NSecsPerSec - 1;
|
||||
Exit;
|
||||
end;
|
||||
Inc(UnixTime.sec);
|
||||
Dec(UnixTime.nanosec, NSecsPerSec);
|
||||
end;
|
||||
if (UnixTime.nanosec < 0) then
|
||||
begin
|
||||
if (UnixTime.sec = Low(Int64)) then
|
||||
begin
|
||||
UnixTime.nanosec:= 0;
|
||||
end
|
||||
else begin
|
||||
Dec(UnixTime.sec);
|
||||
Inc(UnixTime.nanosec, NSecsPerSec);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function UnixFileTimeToDateTime(UnixTime: TUnixFileTime) : TDateTime;
|
||||
var
|
||||
filetime: DCBasicTypes.TFileTimeEx;
|
||||
|
|
@ -549,8 +536,6 @@ var
|
|||
ATime: TTimeStruct;
|
||||
Milliseconds: Word;
|
||||
begin
|
||||
NormalizeFileTime(UnixTime);
|
||||
|
||||
if (fpLocalTime(@UnixTime.sec, @ATime) = nil) then
|
||||
Exit(UnixEpoch);
|
||||
|
||||
|
|
@ -650,7 +635,7 @@ begin
|
|||
if (AUnixTime = -1) then
|
||||
Result:= TFileTimeExNull
|
||||
else begin
|
||||
Result:= TFileTimeEx.create(AUnixTime, MilliSecond*1000*1000);
|
||||
Result:= TFileTimeEx.Create(AUnixTime, MilliSecond * 1000 * 1000);
|
||||
end;
|
||||
end;
|
||||
{$ELSE}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue