Parcourir la source

File datetime UTC support

git-svn-id: trunk@47210 -
(cherry picked from commit b51729dac5db8f713b2e777e374d9811c83e0f52)
ondrej il y a 4 ans
Parent
commit
84b6cee4f7

+ 4 - 14
packages/rtl-objpas/src/inc/dateutil.inc

@@ -2692,35 +2692,25 @@ end;
 function UniversalTimeToLocal(UT: TDateTime): TDateTime;
 
 begin
-  Result:=UniversalTimeToLocal(UT,-GetLocalTimeOffset(UT));
+  Result:=SysUtils.UniversalTimeToLocal(UT,-GetLocalTimeOffset(UT));
 end;
 
 function UniversalTimeToLocal(UT: TDateTime; TZOffset : Integer): TDateTime;
 
 begin
-  if (TZOffset > 0) then
-    Result := UT + EncodeTime(TZOffset div 60, TZOffset mod 60, 0, 0)
-  else if (TZOffset < 0) then
-    Result := UT - EncodeTime(Abs(TZOffset) div 60, Abs(TZOffset) mod 60, 0, 0)
-  else
-    Result := UT;
+  Result:=SysUtils.UniversalTimeToLocal(UT,TZOffset);
 end;
  
 Function LocalTimeToUniversal(LT: TDateTime): TDateTime;
 
 begin
-  Result:=LocalTimeToUniversal(LT,-GetLocalTimeOffset(LT));
+  Result:=SysUtils.LocalTimeToUniversal(LT,-GetLocalTimeOffset(LT));
 end;
 
 Function LocalTimeToUniversal(LT: TDateTime;TZOffset: Integer): TDateTime;
 
 begin
-  if (TZOffset > 0) then
-    Result := LT - EncodeTime(TZOffset div 60, TZOffset mod 60, 0, 0)
-  else if (TZOffset < 0) then
-    Result := LT + EncodeTime(Abs(TZOffset) div 60, Abs(TZOffset) mod 60, 0, 0)
-  else
-    Result := LT;
+  Result:=SysUtils.LocalTimeToUniversal(LT,TZOffset);
 end;
 
 Const

+ 52 - 0
rtl/objpas/sysutils/dati.inc

@@ -1298,6 +1298,21 @@ begin
 end;
 {$endif unix}
 
+Function FileDateToUTC (Filedate : Int64) : TDateTime;
+
+{$ifndef unix}
+begin
+  Result := LocalTimeToUniversal(FileDateToDateTime(Filedate));
+end;
+{$else unix}
+var
+  y, mon, d, h, min, s: word;
+begin
+  EpochToUniversal(FileDate,y,mon,d,h,min,s);
+  Result:=ComposeDateTime(EncodeDate(y,mon,d),EncodeTime(h,min,s,0));
+end;
+{$endif unix}
+
 function TryStrToDate(const S: ShortString; out Value: TDateTime): Boolean;
 begin
     result := TryStrToDate(S, Value, #0);
@@ -1533,3 +1548,40 @@ begin
   if not GetLocalTimeOffset(DateTime, Result) then
     Result:=GetLocalTimeOffset();
 end;
+
+{ Conversion of UTC to local time and vice versa }
+
+function UniversalTimeToLocal(UT: TDateTime): TDateTime;
+
+begin
+  Result:=UniversalTimeToLocal(UT,-GetLocalTimeOffset(UT));
+end;
+
+function UniversalTimeToLocal(UT: TDateTime; TZOffset : Integer): TDateTime;
+
+begin
+  if (TZOffset > 0) then
+    Result := UT + EncodeTime(TZOffset div 60, TZOffset mod 60, 0, 0)
+  else if (TZOffset < 0) then
+    Result := UT - EncodeTime(Abs(TZOffset) div 60, Abs(TZOffset) mod 60, 0, 0)
+  else
+    Result := UT;
+end;
+
+Function LocalTimeToUniversal(LT: TDateTime): TDateTime;
+
+begin
+  Result:=LocalTimeToUniversal(LT,-GetLocalTimeOffset(LT));
+end;
+
+Function LocalTimeToUniversal(LT: TDateTime;TZOffset: Integer): TDateTime;
+
+begin
+  if (TZOffset > 0) then
+    Result := LT - EncodeTime(TZOffset div 60, TZOffset mod 60, 0, 0)
+  else if (TZOffset < 0) then
+    Result := LT + EncodeTime(Abs(TZOffset) div 60, Abs(TZOffset) mod 60, 0, 0)
+  else
+    Result := LT;
+end;
+

+ 8 - 0
rtl/objpas/sysutils/datih.inc

@@ -203,3 +203,11 @@ function GetLocalTimeOffset: Integer;
 function GetLocalTimeOffset(const DateTime: TDateTime; out Offset: Integer): Boolean;
 function GetLocalTimeOffset(const DateTime: TDateTime): Integer;
 
+Function FileDateToUTC (Filedate : Int64) : TDateTime;
+
+{ UTC <-> Local time }
+Function UniversalTimeToLocal(UT: TDateTime): TDateTime;
+Function UniversalTimeToLocal(UT: TDateTime; TZOffset : Integer): TDateTime;
+Function LocalTimeToUniversal(LT: TDateTime): TDateTime;
+Function LocalTimeToUniversal(LT: TDateTime; TZOffset: Integer): TDateTime;
+

+ 80 - 0
rtl/objpas/sysutils/filutil.inc

@@ -119,12 +119,38 @@ begin
 end;
 
 
+function FileAgeUTC(const FileName: RawByteString; out FileDateTimeUTC: TDateTime; FollowLink: Boolean = True): Boolean;
+Var
+  Info : TRawByteSearchRec;
+  A : Integer;
+begin
+  for A:=1 to Length(FileName) do
+    if CharInSet(FileName[A],['?','*']) then
+      Exit(False);
+  A:=0;
+  if not FollowLink then
+    A:=A or faSymLink;
+  Result:=FindFirst(FileName,A,Info)=0;
+  if Result then
+    begin
+      FileDateTimeUTC:=FileDateToUTC(Info.Time);
+      FindClose(Info);
+    end;
+end;
+
+
 Function FileAge(const FileName: UnicodeString; out FileDateTime: TDateTime; FollowLink: Boolean = True): Boolean;
 begin
   Result:=FileAge(ToSingleByteFileSystemEncodedFileName(FileName),FileDateTime,FollowLink);
 end;
 
 
+Function FileAgeUTC(const FileName: UnicodeString; out FileDateTimeUTC: TDateTime; FollowLink: Boolean = True): Boolean;
+begin
+  Result:=FileAgeUTC(ToSingleByteFileSystemEncodedFileName(FileName),FileDateTimeUTC,FollowLink);
+end;
+
+
 function FileGetSymLinkTarget(const FileName: UnicodeString; out SymLinkRec: TUnicodeSymLinkRec): Boolean;
 var
   sr: TRawbyteSymLinkRec;
@@ -334,12 +360,39 @@ begin
 end;
 
 
+function FileAgeUTC(const FileName: UnicodeString; out FileDateTimeUTC: TDateTime; FollowLink: Boolean = True): Boolean;
+Var
+  Info : TUnicodeSearchRec;
+  A : Integer;
+
+begin
+  for A:=1 to Length(FileName) do
+    if CharInSet(FileName[A],['?','*']) then
+      Exit(False);
+  A:=0;
+  if not FollowLink then
+    A:=A or faSymLink;
+  Result:=FindFirst(FileName,A,Info)=0;
+  if Result then
+    begin
+      FileDateTimeUTC:=Info.TimeStampUTC;
+      FindClose(Info);
+    end;
+end;
+
+
 Function FileAge(const FileName: RawbyteString; out FileDateTime: TDateTime; FollowLink: Boolean = True): Boolean;
 begin
   Result:=FileAge(UnicodeString(FileName),FileDateTime,FollowLink);
 end;
 
 
+function FileAgeUTC(const FileName: RawByteString; out FileDateTimeUTC: TDateTime; FollowLink: Boolean = True): Boolean;
+begin
+  Result:=FileAgeUTC(UnicodeString(FileName),FileDateTimeUTC,FollowLink);
+end;
+
+
 function FileGetSymLinkTarget(const FileName: RawByteString; out SymLinkRec: TRawbyteSymLinkRec): Boolean;
 var
   sr: TUnicodeSymLinkRec;
@@ -617,6 +670,15 @@ begin
       aResult := SystemTimeToDateTime(st);
   end;
 end;
+
+function FindDataTimeToUTC(constref aFileTime: FILETIME; out aResult: TDateTime): Boolean;
+var
+  st: TSystemTime;
+begin
+  Result := FileTimeToSystemTime(aFileTime, st);
+  if Result then
+    aResult := SystemTimeToDateTime(st);
+end;
 {$endif}
 
 { TUnicodeSearchRec }
@@ -640,6 +702,15 @@ begin
   Result:=IsDirectory and ((Name='.') or (Name='..'));
 end;
 
+function TUnicodeSearchRec.GetTimeStampUTC: TDateTime;
+begin
+{$if declared(FindDataTimeToUTC)}
+  if not FindDataTimeToUTC(FindData.ftLastWriteTime, Result) then
+{$else}
+  Result := FileDateToUTC(Time);
+{$endif}
+end;
+
 { TRawbyteSearchRec }
 
 function TRawbyteSearchRec.GetTimeStamp: TDateTime;
@@ -661,6 +732,15 @@ begin
   Result:=IsDirectory and ((Name='.') or (Name='..'));
 end;
 
+function TRawbyteSearchRec.GetTimeStampUTC: TDateTime;
+begin
+{$if declared(FindDataTimeToDateTime)}
+  if not FindDataTimeToUTC(FindData.ftLastWriteTime, Result) then
+{$else}
+  Result := FileDateToUTC(Time);
+{$endif}
+end;
+
 { TUnicodeSymLinkRec }
 
 function TUnicodeSymLinkRec.GetTimeStamp: TDateTime;

+ 6 - 0
rtl/objpas/sysutils/filutilh.inc

@@ -63,10 +63,12 @@ Type
 {$endif}
   private
     function GetTimeStamp: TDateTime;
+    function GetTimeStampUTC: TDateTime;
   public
     Function IsDirectory : Boolean; inline;
     function IsCurrentOrParentDir: Boolean; inline;
     property TimeStamp: TDateTime read GetTimeStamp;
+    property TimeStampUTC: TDateTime read GetTimeStampUTC;
   end;
 
   { TRawbyteSearchRec }
@@ -86,10 +88,12 @@ Type
 {$ENDIF}
   private
     function GetTimeStamp: TDateTime;
+    function GetTimeStampUTC: TDateTime;
   public
     Function IsDirectory : Boolean; inline;
     function IsCurrentOrParentDir: Boolean; inline;
     property TimeStamp: TDateTime read GetTimeStamp;
+    property TimeStampUTC: TDateTime read GetTimeStampUTC;
   end;
 
 {$IFDEF FPC_UNICODE_RTL}
@@ -199,6 +203,7 @@ Function FileSearch (Const Name, DirList : UnicodeString; ImplicitCurrentDir : B
 Function ExeSearch  (Const Name : UnicodeString; Const DirList : UnicodeString = '') : UnicodeString;
 Function FileIsReadOnly(const FileName : UnicodeString): Boolean;
 function FileAge(const FileName: UnicodeString; out FileDateTime: TDateTime; FollowLink: Boolean = True): Boolean;
+function FileAgeUTC(const FileName: UnicodeString; out FileDateTimeUTC: TDateTime; FollowLink: Boolean = True): Boolean;
 function FileGetSymLinkTarget(const FileName: UnicodeString; out SymLinkRec: TUnicodeSymLinkRec): Boolean;
 function FileGetSymLinkTarget(const FileName: UnicodeString; out TargetName: UnicodeString): Boolean; inline;
 
@@ -219,6 +224,7 @@ Function FileSearch (Const Name, DirList : RawByteString; ImplicitCurrentDir : B
 Function ExeSearch  (Const Name : RawByteString; Const DirList : RawByteString = '') : RawByteString;
 Function FileIsReadOnly(const FileName: RawByteString): Boolean;
 function FileAge(const FileName: RawByteString; out FileDateTime: TDateTime; FollowLink: Boolean = True): Boolean;
+function FileAgeUTC(const FileName: RawByteString; out FileDateTimeUTC: TDateTime; FollowLink: Boolean = True): Boolean;
 {$ifndef FPUNONE}
 Function FileAge (Const FileName : RawByteString): Int64;
 {$endif}

+ 11 - 0
rtl/unix/unixutil.pp

@@ -52,6 +52,7 @@ Function StringToPPChar(Var S:RawByteString;ReserveEntries:integer):ppchar;
 function ArrayStringToPPchar(const S:Array of RawByteString;reserveentries:Longint):ppchar; // const ?
 Function LocalToEpoch(year,month,day,hour,minute,second:Word):int64; deprecated 'use DateUtils.DateTimeToUnix';
 Procedure EpochToLocal(epoch:int64;var year,month,day,hour,minute,second:Word); deprecated 'use DateUtils.UnixToDateTime';
+Procedure EpochToUniversal(epoch:int64;var year,month,day,hour,minute,second:Word); deprecated 'use DateUtils.UnixToDateTime';
 Procedure JulianToGregorian(JulianDN:LongInt;Var Year,Month,Day:Word); deprecated 'use DateUtils.DateTimetoJulianDate';
 Function GregorianToJulian(Year,Month,Day:Longint):LongInt; deprecated 'use DateUtils.JulianDateToDateTime';
 
@@ -210,6 +211,16 @@ Var
   DateNum: LongInt;
 Begin
   inc(Epoch,TZSeconds);
+  EpochToUniversal(epoch,year,month,day,hour,minute,second);
+End;
+
+Procedure EpochToUniversal(epoch:Int64;var year,month,day,hour,minute,second:Word);
+{
+  Transforms Epoch time into universal time (hour, minute,seconds)
+}
+Var
+  DateNum: LongInt;
+Begin
   Datenum:=(Epoch Div 86400) + c1970;
   JulianToGregorian(DateNum,Year,Month,day);
   Epoch:=Abs(Epoch Mod 86400);