简而言之我的问题:TDateTime A
(03.09.2014 13:40)- TDateTime B
(03.09.2014 13:40)= -1
我有两个要比较的 TDateTime 值,首先我使用=
运算符检查它们是否相同,但经过几次测试后,我意识到这在我的情况下不起作用。令人困惑的是,它在大多数时候都能很好地工作,但有时却不行。
我LastWriteTime
从现有文件的属性中获取一个值,另一个值来自 MySQL 数据库。
这是一些代码:
TDateTime a := FileList[loop].Lastwritetime.AsUTCDateTime; // TDateTime from MySQL
TDateTime b := GetLastwritetimeUtc(Sourcedirectory); // TDateTime from my local file
if (CompareDateTime(a, b) = 0) then
begin
// do some stuff.
end;
现在正如之前提到的,这个简单的代码大部分时间都在工作,但是对于某些TDateTime
值,我得到一个否定的结果,这应该意味着我TDateTime
来自 MySQL 数据库的值比我的本地文件TDateTime
值更早。
于是我开始调试:
double aTicks := a; // MySQL TDateTime
double bTicks := b; // Local file TDateTime
这为我提供了自 30.12.1899 以来经过的天数以及时间的十进制值。
示例值:
// a = 02.09.2014 11:42:01
// b = 02.09.2014 11:42:01
// aTicks = 41884,4875115741
// bTicks = 41884,4875153356
不同的小数是否应该是毫秒(从 xxxx,4875 开始)?现在,如果我比较它们(例如CompareDateTime(a,b)
或a = b
),我不会得到0
/ true
(我不比较aTicks
和bTicks
值)。
我是否必须以获取本地文件的方式进行更改TDateTime
(目前我正在使用 WinAPI,GetLastWriteTimeUTC
没有为我提供正确的 UTC 时间)?
我认为这不是一个真正的难题,但我不知道如何解决这个问题。``是否TDateTime
存储隐藏的毫秒?在调试模式下,我看不到任何毫秒,我不知道如何从我的TDateTime
(使用 Delphi XE2)中获取这个值。
以下是关于我的项目的一些额外细节
我以TDateTime b
这种方式获得价值
function GetLastwritetimeUtc(source: String): TDateTime;
var
fad: TWin32FileAttributeData;
SystemTime: TSystemTime;
lastwritetimeUtc: TDateTime;
begin
GetFileAttributesEx(PWideChar(source),GetFileExInfoStandard,@fad);
FileTimeToSystemTime(fad.ftLastWriteTime, SystemTime);
lastwritetimeUtc := SystemTimeToDateTime(SystemTime);
result := lastwritetimeUtc;
end;
如果来自 MySQL 数据库的文件“较新”,我将替换它并以这种方式设置LastWriteTime
来自我的 MySQLTDateTime a
属性:(SetLastWriteTimeUTC(a)
并且我TDateTime
来自 MySQL (a) 的值没有任何毫秒值)。所以问题不应该再次发生,但它确实发生了。
TDateTime
我的 MySQL 数据库上的值来自这个
XSDateTime c := DateTimeToXSDateTime(GetLastwritetimeUtc(sourceDirectory));
// i send this via WCF service to the MySQL database and store it in a `TDateTime` column (which does not include milliseconds)
我希望这是足够的信息,而不是太多。
此致,
尼古拉斯
更新:
该代码与我的主程序“相同”,正如我上面所说,错误的 DateTime 比较不会一直只在某些文件上触发(在我的情况下是 $Default10.dsk)。
uses
SysUtils,
Soap.SoapHttpTrans,
DateUtils,
Windows,
System.IOUtils,
Soap.XSBuiltIns;
var
fad: TWin32FileAttributeData;
SystemTime: TSystemTime;
lastwritetimeUtcA: TDateTime;
lastwritetimeUtcB: TDateTime;
sourceFileA: string;
sourceFileB: string;
lastwritetimeXS: TXSDateTime;
begin
while True do
begin
sourceFileA := 'Path to a file on your computer no matter which';
sourceFileB := 'Path to another file on your computer no matter which';
//GetLastWriteTime from local file
GetFileAttributesEx(PWideChar(sourceFileA),GetFileExInfoStandard,@fad);
FileTimeToSystemTime(fad.ftLastWriteTime, SystemTime);
lastwritetimeUtcA := SystemTimeToDateTime(SystemTime);
//Set the localfile lastwritetime to the theoretical mySQL file
// in my main program there does not exist a mySQL file (only a value of TDateTime in the TDateTime column of my database where i store the lastwritetime from the local files
TFile.SetLastWriteTimeUtc(sourceFileB, lastwritetimeUtcA);
//Get the LastWriteTime from theoretical mySQL file
// in my main program i get the lastwritetime value from the MySQL database via WCF that is the reason for the convertion of XSDateTime.AsUTCDateTime and DateTimeToXSDateTime
GetFileAttributesEx(PWideChar(sourceFileB),GetFileExInfoStandard,@fad);
FileTimeToSystemTime(fad.ftLastWriteTime, SystemTime);
lastwritetimeUtcB := SystemTimeToDateTime(SystemTime);
//Convert lastwritetime to XSDatetime - how i do it in my program
lastwritetimeXS := DateTimeToXSDateTime(lastwritetimeUtcB);
{Convert it back to DateTime}
lastwritetimeUtcB := lastwritetimeXS.AsUTCDateTime;
//Compare them
if lastwritetimeUtcA = lastwritetimeUtcB then
Writeln('Same time')
else
writeln('Not same time');
Sleep(500);
end;
end;