TTimePicker 在更改时添加 1899/12/30 日期

0 delphi formatdatetime tdatetime delphi-11-alexandria

我正忙着用 Delphi 11.3 编写一个与时间兼容的程序。具体来说,是开始时间和结束时间,并计算两者之间花费的时间,以及其中一个是否大于另一个。

MinutesBetween()尽管使用了or ,事情还是变得一团糟MinuteSpan()。我的开始时间可能是08:00我的结束时间09:30。如果我使用if start < end,我会得到 False 但它是 True 。计算所花费的时间相当于100多年。像这样的奇怪的事情。

作为测试,我编写了一个小程序,代码如下:

mmo1.Lines.Add(FormatDateTime('yyyy/mm/dd hh:nn:ss.zzz',tmpckr1.Time)+'   '
+FormatDateTime('yyyy/mm/dd hh:nn:ss.zzz',tmpckr2.Time)+'   '
+IntToStr(MinutesBetween(tmpckr1.Time,tmpckr2.Time))+'   '
+FloatToStr(MinuteSpan(tmpckr1.Time,tmpckr2.Time)));
Run Code Online (Sandbox Code Playgroud)

这是在一个TTimer. 输出如预期:

mmo1.Lines.Add(FormatDateTime('yyyy/mm/dd hh:nn:ss.zzz',tmpckr1.Time)+'   '
+FormatDateTime('yyyy/mm/dd hh:nn:ss.zzz',tmpckr2.Time)+'   '
+IntToStr(MinutesBetween(tmpckr1.Time,tmpckr2.Time))+'   '
+FloatToStr(MinuteSpan(tmpckr1.Time,tmpckr2.Time)));
Run Code Online (Sandbox Code Playgroud)

我将单击tmpckr1,然后在底部打勾。请注意,我当时没有更改任何内容,这就是结果。

2023/09/18 20:46:29.571   2023/09/18 20:46:29.571   0   0
Run Code Online (Sandbox Code Playgroud)

我重复一遍,这次是tmpckr2

1899/12/30 20:46:29.571   2023/09/18 20:46:29.571   65069280   65069280
Run Code Online (Sandbox Code Playgroud)

有没有办法防止这种情况发生,或者我必须使用EncodeDate()、 、做一些魔法EncodeTime()ReplaceDate()以便s的值ReplaceTime()真正匹配,还是我让事情变得过于复杂?TTimeTTimePicker

如果我只是处理TTime,为什么日期是一个因素?TTimePicker为什么一旦有活动,日期就会改变OnChange

Rem*_*eau 5

您要求输出未定义日期组件的值FormatDateTime()的日期。TTime

TDateTTime、 和TDateTime都只是 的别名Double,其中“日期部分”表示 的1899-12-30整数部分何时Double0

TTimePicker.Time应该返回一个仅包含时间部分而不是日期部分的值TTime因此,您的输出包含非零日期的事实显然是一个错误,但这并不重要,因为您应该忽略开始的日期,因为它在这种情况下没有定义的含义。

您需要修复代码以在格式化TTimePicket.Time值时忽略日期。我还发现在处理包含未定义组件的 // 值时最好使用 RTL 和函数,尤其是DateOf()在这种情况下由 UI 控件(如、、等)返回的值。TimeOf()TDateTTimeTDateTimeTDateTimePickerTMonthCalendarTTimePicker

尝试这个:

FormatDateTime('hh:nn:ss.zzz', TimeOf(tmpckr1.Time))
FormatDateTime('hh:nn:ss.zzz', TimeOf(tmpckr2.Time))

// just to demonstrate that a zero date is being returned properly...
FormatDateTime('yyyy/mm/dd hh:nn:ss.zzz', TimeOf(tmpckr1.Time))
FormatDateTime('yyyy/mm/dd hh:nn:ss.zzz', TimeOf(tmpckr2.Time))

MinutesBetween(TimeOf(tmpckr1.Time), TimeOf(tmpckr2.Time)))
MinuteSpan(TimeOf(tmpckr1.Time), TimeOf(tmpckr2.Time)))
Run Code Online (Sandbox Code Playgroud)
start := TimeOf(tmpckr1.Time);
end := TimeOf(tmpckr2.Time);
if start < end then ...
Run Code Online (Sandbox Code Playgroud)