unit BonMarGestDataOra;
{$mode objfpc}{$H+}
interface
uses LazFileUtils, LazUTF8, SysUtils, dateutils
{$IFDEF UNIX}
, Unix, unixutil
{$ELSE}
, windows
{$ENDIF}
;
const CstConvDataErr=-1;
function UnixTimeToLocalTime(UnixFileTime: Int64; var WrkDateTime:TDateTime):Boolean;
{$IFDEF MSWINDOWS}
function UTCFileTimeToLocalTime(UTCFileTime: TFileTime; var WrkDateTime:TDateTime):Boolean;
{$ENDIF}
function DataUltimaModifica(const NomeFile:String):TDateTime;
function DataDiCreazione(const NomeFile: String): TDateTime;
implementation
var
{$IFDEF UNIX}
SegnaPosto:Integer; //Messa solo per non adre errori di compilazione in Linux
{$ELSE}
TZ: _TIME_ZONE_INFORMATION;
{$ENDIF}
{$IFDEF UNIX}
function UnixTimeToLocalTime(UnixFileTime: Int64; var WrkDateTime:TDateTime):Boolean;
var DiffTimeLinux:Longint;
begin
//Inizializzazione output
Result:=False;
WrkDateTime:=CstConvDataErr;
//Trasformo la Data/Ora Unix in una data normale
WrkDateTime:=UnixToDateTime(UnixFileTime);
//Determino il DST tra la data che devo gestire ed oggi
GetLocalTimezone(UnixFileTime);
DiffTimeLinux:=Tzseconds;
//Rettifico l'orario ed emetto il risultato
WrkDateTime:=IncSecond(WrkDateTime, DiffTimeLinux);
Result:=True;
end;
{$ELSE}
function UnixTimeToLocalTime(UnixFileTime: Int64; var WrkDateTime:TDateTime):Boolean;
var GMTST: TSystemTime;
LocalST: TSystemTime;
ModifyDT: TDateTime;
begin
//Inizializzazione output
Result:=False;
WrkDateTime:=CstConvDataErr;
//Trasformo la Data/Ora Unix in una data normale
WrkDateTime:=UnixToDateTime(UnixFileTime);
//Trasformo la data/ora appena trovata in una di sistema
DateTimeToSystemTime(WrkDateTime, GMTST);
//Converto l'orario in base ai dati della TimeZone
if SystemTimeToTzSpecificLocalTime(@TZ, GMTST, LocalST) then begin
//Converto la data nel formato corretto
ModifyDT:=SystemTimeToDateTime(LocalST);
//Comunico al chiamante che la conversione è andata a buon fine,
//e ladata/ora corretta
WrkDateTime:=ModifyDT;
Result:=True;
end;
end;
{$ENDIF}
{$IFDEF MSWINDOWS}
function UTCFileTimeToLocalTime(UTCFileTime: TFileTime; var WrkDateTime:TDateTime):Boolean;
var GMTST: TSystemTime;
LocalST: TSystemTime;
ModifyDT: TDateTime;
begin
//Inizializzazione output
Result:=False;
WrkDateTime:=CstConvDataErr;
//Converto la data di un file in una data di sistema
if FileTimeToSystemTime(UTCFileTime, GMTST) then begin
//Converto l'orario in base ai dati della TimeZone
if SystemTimeToTzSpecificLocalTime(@TZ, GMTST, LocalST) then begin
//Converto la data nel formato corretto
ModifyDT:=SystemTimeToDateTime(LocalST);
//Comunico al chiamante che la conversione è andata a buon fine,
//e ladata/ora corretta
WrkDateTime:=ModifyDT;
Result:=True;
end;
end;
end;
{$ENDIF}
{Restituisco la data & ora di ultima modifica.
ATTENZIONE: DirInfo.Time restituisce la data di creazione, non modifica !!!}
{$IFDEF MSWINDOWS}
{
function DataUltimaModifica(const NomeFile:String;TipoRitorno:TipoData):TDateTime;
var hFile:Integer;
ftModifica, ftCreazione, ftAccesso:TFileTime;
sysDateTime:_SYSTEMTIME;
begin
Result:=CstConvDataErr;
hFile:=0;
try
hFile:=CreateFile(PChar(NomeFile),
GENERIC_READ ,
FILE_SHARE_READ or FILE_SHARE_WRITE, //Faccio in modo di poter reperire la data
nil, //anche dai files vincolati
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
0);
if (GetLastError = 0) then begin
GetFileTime(hFile, @ftCreazione, @ftAccesso, @ftModifica);
if (GetLastError = 0) then begin
FileTimeToLocalFileTime(ftModifica, ftModifica);
FileTimeToSystemTime(ftModifica, sysDateTime);
Result:=SystemTimeToDateTime(sysDateTime);
end;
end;
finally
if (hFile <> 0) then begin
CloseHandle(hFile);
end;
end;
end;
}
function DataUltimaModifica(const NomeFile:String):TDateTime;
var DirInfo: TSearchRec;
UTCFileTime: TFileTime;
WrkDateTime:TDateTime;
begin
Result:=CstConvDataErr;
try
if FindFirstUTF8(NomeFile, faAnyFile, DirInfo) = 0 then begin
UTCFileTime:=DirInfo.FindData.ftLastWriteTime;
if UTCFileTimeToLocalTime(UTCFileTime, WrkDateTime) then begin
Result:=WrkDateTime;
end;
end;
finally
FindCloseUTF8(DirInfo);
end;
end;
function DataDiCreazione(const NomeFile: String): TDateTime;
var DirInfo:TSearchRec;
ftCreazione:TFileTime;
WrkDateTime:TDateTime;
begin
Result:=CstConvDataErr;
try
if (FindFirstUTF8(NomeFile, faAnyFile, DirInfo) = 0) then begin
ftCreazione:=DirInfo.FindData.ftCreationTime;
if UTCFileTimeToLocalTime(ftCreazione, WrkDateTime) then begin
Result:=WrkDateTime;
end;
{
FileTimeToLocalFileTime(ftCreazione, ftCreazione);
FileTimeToSystemTime(ftCreazione, sysDateTime);
Result:=SystemTimeToDateTime(sysDateTime);
}
end;
finally
LazFileUtils.FindCloseUTF8(DirInfo);
end;
end;
{$ELSE}
function DataUltimaModifica(const NomeFile:String):TDateTime;
var DataFile:Longint;
begin
DataFile:=FileAgeUTF8(NomeFile);
//In caso di file non trovato, DataFile vale -1
if (DataFile = -1) then begin
Result:=CstConvDataErr;
end else begin
UnixTimeToLocalTime(DataFile, Result);
end;
end;
function DataDiCreazione(const NomeFile: String): TDateTime;
var DataFile:Longint;
DirInfo:TSearchRec;
begin
{
//In linux la data di creazione di un file non viene salvata
//https://www.cyberciti.biz/tips/understanding-unixlinux-filesystem-inodes.html
=> File type (executable, block special etc)
=> Permissions (read, write etc)
=> Owner
=> Group
=> File Size
=> File access, change and modification time (remember UNIX or Linux never stores
file creation time, this is favorite question asked in UNIX/Linux sys admin job interview)
=> File deletion time
=> Number of links (soft/hard)
=> Extended attribute such as append only or no one can delete file including root
user (immutability)
=> Access Control List (ACLs)
All the above information stored in an inode.
In short the inode identifies the file and its attributes (as above).
Each inode is identified by a unique inode number within the file system.
Inode is also know as index number. }
Result:=DataUltimaModifica(NomeFile);
end;
{$ENDIF}
initialization
//Questa operazione, se usata per ogni file, ad esempio perché sto elaborando un elenco,
//potrebbe durare parecchio, quindi la lancio una volta sola
{$IFDEF UNIX}
ReadTimezoneFile(GetTimezoneFile);
{$ELSE}
GetTimeZoneInformation(TZ);
{$ENDIF}
finalization;
end.