我有一个实用程序,用于比较源文件日期/时间。这在大多数情况下都有效,但在比较不同时区的文件的日期/时间时会失败。所以我需要一个UTC日期时间例程。
从环顾四周看来,Windows API GetFileTime似乎支持这一点。我也找到了这个包装程序,但是在Delphi 2010下编译时,它在GetFileTime调用时崩溃。
有什么想法吗?或者是否有人有一段处理UTC时区等的代码,我可以通过2个文件名来告诉我它们是否不同?
function CompareFileTimes(File1, File2 : String) : LongInt;
var
F1, F2 : THandle;
F1_CreateTime,
F1_LastAccess,
F1_LastWrite,
F2_CreateTime,
F2_LastAccess,
F2_LastWrite : PFileTime;
begin
//Initialize all variables
F1 := 0;
F2 := 0;
//Since these are pointers, we have to
//allocate memory for the FileTime structures
GetMem(F1_CreateTime, SizeOf(TFileTime));
GetMem(F1_LastAccess, SizeOf(TFileTime));
GetMem(F1_LastWrite, SizeOf(TFileTime));
GetMem(F2_CreateTime, SizeOf(TFileTime));
GetMem(F2_LastAccess, SizeOf(TFileTime));
GetMem(F2_LastWrite, SizeOf(TFileTime));
//Fill the structures with nulls for now
FillChar(F1_CreateTime, SizeOf(TFileTime), #0);
FillChar(F1_LastAccess, SizeOf(TFileTime), #0);
FillChar(F1_LastWrite, SizeOf(TFileTime), #0);
FillChar(F2_CreateTime, SizeOf(TFileTime), #0);
FillChar(F2_LastAccess, SizeOf(TFileTime), #0);
FillChar(F2_LastWrite, SizeOf(TFileTime), #0);
//Get file handles for the files in question
//Notice that even though we're using CreateFile
//the open disposition for the file is OPEN_EXISTING
F1 := CreateFile(PChar(F1), 0, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
F2 := CreateFile(PChar(F2), 0, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
//Get the file times for the files.
GetFileTime(F1, F1_CreateTime, F1_LastAccess, F1_LastWrite);
GetFileTime(F2, F2_CreateTime, F2_LastAccess, F2_LastWrite);
//Assign the function's result to comparison
//-1, File1 is younger than File2
//0, File1 is the same as File2
//+1 File1 is older than File2
Result := CompareFileTime(F1_CreateTime^, F2_CreateTime^);
//Free the memory allocated to the pointers
FreeMem(F1_CreateTime, SizeOf(TFileTime));
FreeMem(F1_LastAccess, SizeOf(TFileTime));
FreeMem(F1_LastWrite, SizeOf(TFileTime));
FreeMem(F2_CreateTime, SizeOf(TFileTime));
FreeMem(F2_LastAccess, SizeOf(TFileTime));
FreeMem(F2_LastWrite, SizeOf(TFileTime));
end;
非常感谢任何帮助。
答案 0 :(得分:4)
Delphi 2010已经包含一个简单的包装器,用于在ioutils.pas中获取UTC时间。这是一段比较文件的UTC创建时间的代码。
uses
IOUtils, DateUtils;
function CompareFileCreationTimeUtc(const aFile1, aFile2: String): integer;
var
lCreationTime1: TDateTime;
lCreationTime2: TDateTime;
begin
lCreationTime1 := TFile.GetCreationTimeUtc(aFile1);
lCreationTime2 := TFile.GetCreationTimeUtc(aFile2);
Result := CompareDateTime(lCreationTime1, lCreationTime2);
end;
答案 1 :(得分:1)
如果您不想使用IOUtils例程并且喜欢自己做,那么您的功能应该像(未经测试)一样进行更正:
function CompareFileTimes(File1, File2 : String) : LongInt;
var
F1, F2: THandle;
F1_CreateTime, F2_CreateTime: TFileTime;
begin
//Fill the structures with nulls for now
ZeroMemory(@F1_CreateTime, SizeOf(TFileTime));
ZeroMemory(@F2_CreateTime, SizeOf(TFileTime));
//Get file handles for the files in question
//Notice that even though we're using CreateFile
//the open disposition for the file is OPEN_EXISTING
F1 := CreateFile(PChar(File1), 0, FILE_SHARE_READ , nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
F2 := CreateFile(PChar(File2), 0, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (F1=INVALID_HANDLE_VALUE) or (F1=INVALID_HANDLE_VALUE) then
RaiseLastOSError;
//Get the file times for the files.
if not GetFileTime(F1, @F1_CreateTime, nil, nil) or
not GetFileTime(F2, @F2_CreateTime, nil, nil) then
RaiseLastOSError;
//Assign the function's result to comparison
//-1, File1 is younger than File2
//0, File1 is the same as File2
//+1 File1 is older than File2
Result := CompareFileTime(F1_CreateTime, F2_CreateTime);
end;