Delphi:SetFileDate创建错误的LastWriteTime(Summer / Wintertime)

时间:2014-08-25 12:30:27

标签: delphi datetime file-attributes

我正在从我的服务器下载文件(我只获取字节和lastwritetime属性的DateTime),在下载数据后,我在本地机器上创建了一个新文件,并想设置lastwritetime属性。 为此,我使用以下方法:

procedure SetFileDate(const FileName: string; NewDate: TDateTime);
var
    FileDate, FileHandle: Integer;
begin
    try
        FileDate := DateTimeToFileDate(NewDate);

        FileHandle := FileOpen(FileName, fmOpenReadWrite or fmShareDenyWrite);
        if FileHandle > 0 then
            begin
                FileSetDate(FileHandle, FileDate);
                FileClose(FileHandle);
            end;
    except
        begin
            // ERROR Log
            err.Msg('FileReqThrd.SetFileDate');
        end;
    end;
end;

对于“新日期”'参数我使用从我的服务器获得的DateTime。 我试图像这样从服务器转换DateTime以获得有效的lastwritetime(我从WCF请求数据,这就是我将其转换为UTCDateTime的原因,来自WCF服务的未触摸数据是TXSDateTime):

TDateTime cloudFileDateTime := StrToDateTime(DateTimeToStr(cloudDownloadResult.FileCloudData.Lastwritetime.AsUTCDateTime));

但最后我的lastwritetime属性来自于冬季期间具有lastwritetime的文件-1h是错误的。

我希望你能理解我的问题,并能让我知道如何解决它。

祝你好运

2 个答案:

答案 0 :(得分:3)

最简单的方法是从System.IOUtils单元拨打TFile.SetLastWriteTimeUtc

TFile.SetLastWriteTimeUtc(FileName, 
    DateTimeUtc);

如果此功能不可用,请使用Win32 API函数SetFileTime

在该方案中,您还需要DateTimeToSystemTime,然后SystemTimeToFileTime

答案 1 :(得分:0)

David提供的答案(使用TFile.SetLastWriteTimeUtc)是正确的。但是,在注释中对错误进行了一些讨论。由于无法发表评论(由于缺少代表),因此我将在此处添加此信息,以供以后遇到此问题的任何人使用。

虽然TFile.SetLastWriteTimeUtc正常工作,但TFile.GetLastWriteTimeUtc确实存在与夏时制有关的错误。 Embarcadero有一个bug report档案,看来他们已经在Delphi 10.3 Rio中修复了它(尽管我还没有尝试过)。

如果您使用的是较早版本的Delphi,则必须使用Windows API来解决此问题。例如GetFileAttributesEx

function GetFileModTimeUtc(filePath: string): TDateTime;
var data: TWin32FindData;
var sysTime: TSystemTime;
begin
  if GetFileAttributesEx(PChar(filePath), GetFileExInfoStandard, @data) and
      FileTimeToSystemTime(data.ftLastWriteTime, sysTime) then begin
    Result := SystemTimeToDateTime(sysTime);
  end else begin
    raise Exception.Create('Unable to get last file write time for ' + filePath);
  end;
end;