我在我的3层应用中本地缓存文件。要检查是从本地缓存还是从服务器读取文件,我比较文件日期。我发现在将文件日期转换为TDateTime时会出现这种情况,反之则存在不一致和值很少匹配的值。这是一些解释问题的代码
procedure TestFileDateConversion;
const
Dir = 'c:\TestDir\';
Filename = 'test.txt';
var
FileDate, NewFileDate: TDateTime;
FilePath: String;
FileHandle: THandle;
begin
ForceDirectories(Dir);
FilePath := concat(Dir, Filename);
// Create the file if it doesn't already exist
FileCreate(FilePath);
FileDate := now;
// Set the file date
try
FileHandle := FileOpen(FileName, fmOpenWrite OR fmShareDenyNone);
if FileHandle > 0 Then
FileSetDate(FileHandle, DateTimeToFileDate(FileDate));
finally
FileClose(FileHandle);
end;
// Check that the expected file date and the actual file date match
if (FileAge(FilePath, NewFileDate)) and (FileDate <> NewFileDate) then
ShowMessage('File dates do not match'); // More often than not, they don't
end;
我确定这是由一些舍入问题引起的。有人知道解决方法吗?
答案 0 :(得分:4)
你对四舍五入是正确的。 TDateTime实际上是一个浮点数,并且所有浮点数都有舍入问题。特别是比较平等是一个问题。 CompareDateTime之类的功能可以提供帮助。还有一些文件系统没有像TDateTime那样的精度。某些文件系统只有2秒的精度。因此,您可能需要使用SecondsBetween函数来决定使用较低的精度进行比较。
答案 1 :(得分:1)
使用Math单元中的'SameValue'函数比较TDateTime。如果两个值彼此非常接近,则执行“模糊”比较,返回相等性(如果您愿意,可以在默认增量内修改)。你的规则应该是:永远不要执行
If FloatA = FloatB then
....
可以这样做:
If FloatA = 0.0 then
....
但就是这样。
布赖恩。
答案 2 :(得分:0)
使用系统日期时间更新文件不是一个好主意,如果你有不同时区的电脑需要骑它。使用哈希函数来知道文件何时不同并且需要更新。
散列文件很简单,例如,请查看http://delphi.about.com/od/objectpascalide/a/delphi-md5-hash.htm。
无论如何,getFileTime的分辨率低于tdatetime(在旧系统中更大),但只有几秒钟,那么你需要在比较中进行一轮。
来自MSDN“并非所有文件系统都能记录创建和上次访问时间,并非所有文件系统都以相同的方式记录它们。例如,在FAT上,创建时间的分辨率为10毫秒,写入时间的分辨率为2秒,访问时间的分辨率为1天(实际上是访问日期)。因此,GetFileTime函数可能不会返回使用SetFileTime设置的相同文件时间信息.NTFS延迟更新文件的上次访问时间到最后一次访问后一小时。“