gpt4 book ai didi

mysql - 忽略 TDateTime 中的毫秒(相同 TDateTime 值相减不为 0)

转载 作者:行者123 更新时间:2023-11-29 12:44:26 27 4
gpt4 key购买 nike

我的问题简而言之: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 值,我得到一个负结果,这应该意味着我来自 MySQL 的 TDateTime 值数据库早于我的本地文件 TDateTime 值。

所以我开始调试:

double aTicks := a; // MySQL TDateTime
double bTicks := b; // Local file TDateTime

这为我提供了自 1899 年 12 月 30 日以来经过的天数以及时间的十进制值。

示例值:

// 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 (我比较 aTicksbTicks 值)。

我是否必须以我获取本地文件TDateTime的方式进行更改(目前我正在使用WinAPI,GetLastWriteTimeUTC没有为我提供正确的世界标准时间)?

我认为这并不是一个真正的难题,但我不知道如何解决这个问题。 `` TDateTime 是否存储隐藏的毫秒数?在 Debug模式下,我看不到任何毫秒,并且我不知道如何从我的 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 数据库中的文件“较新”,我将替换它并从 MySQL TDateTime a 属性中设置 LastWriteTime,如下所示:SetLastWriteTimeUTC(a ) (并且我的 MySQL (a) 中的 TDateTime 值没有任何毫秒值)。所以这个问题不应该再次发生,但它确实发生了。

我的 MySQL 数据库上的 TDateTime 值来自此

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)

我希望这是足够的信息,而不是太多

最诚挚的问候,

尼古拉斯

更新:

该代码与我的主程序“相同”,正如我上面所说,错误的日期时间比较不会始终只在某些文件上触发(在我的例子中是 $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;

最佳答案

如果您想要比较两个 TDateTime 值并匹配秒数,忽略毫秒差异,请使用 DateUtils 单元中的 SecondsBetween:

program Project1;

uses
SysUtils, DateUtils;

var
dtOne, dtTwo: TDateTime;

begin
dtOne := 41884.4875115741;
dtTwo := 41884.4875153356;

if SecondsBetween(dtOne, dtTwo) = 0 then
WriteLn('Dates the same without MS')
else
WriteLn('Not the same dates.');

ReadLn;
end.

如果需要匹配其他分辨率,对于其他差异也有类似的函数,例如 DaysBetweenMinutesBetweenMilliSecondsBetween。这是一个适用于各种分辨率(精确匹配、日、小时、分钟或秒)的实用函数:

type
TDiffResolution = (tdrExact, tdrDay, tdrHour, tdrMin, tdrSec);

function IsSameDateTime(dValOne, dValTwo: TDateTime;
const Resolution: TDiffResolution = tdrSec): Boolean;
begin
case Resolution of
tdrExact: Result := MillisecondsBetween(dValOne, dValTwo) = 0;
tdrDay: Result := IsSameDay(dValOne, dValTwo);
tdrHour: Result := HoursBetween(dValOne, dValTwo) = 0;
tdrMin: Result := MinutesBetween(dValOne, dValTwo) = 0;
tdrSec: Result := SecondsBetween(dValOne, dValTwo) = 0;
else
raise Exception.CreateFmt('Invalid resolution value (%d) provided.',
[Ord(Resolution)]);
end;
end;

使用示例:

  dtOne := 41884.4875115741;
dtTwo := 41884.4875153356;

if IsSameDateTime(dtOne, dtTwo, tdrSec) then
WriteLn('Dates are the same.')
else
WriteLn('Dates are different.');
ReadLn;

关于mysql - 忽略 TDateTime 中的毫秒(相同 TDateTime 值相减不为 0),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25644507/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com