gpt4 book ai didi

delphi - 如何解决 Delphi 无法准确处理日期时间操作的问题?

转载 作者:行者123 更新时间:2023-12-03 14:38:13 25 4
gpt4 key购买 nike

我是 Delphi 新手(现在已经用它编程大约 6 个月了)。到目前为止,这是一次极其令人沮丧的经历,其中大部分来自 Delphi 在处理日期和时间方面的糟糕程度。也许我认为这很糟糕,因为我不知道如何正确使用 TDate 和 TTime,我不知道。这是我现在正在发生的事情:

// This shows 570, as expected
ShowMessage(IntToStr(MinutesBetween(StrToTime('8:00'), StrToTime('17:30'))));

// Here I would expect 630, but instead 629 is displayed. WTF!?
ShowMessage(IntToStr(MinutesBetween(StrToTime('7:00'), StrToTime('17:30'))));

这不是我使用的确切代码,所有内容都在变量中并在另一个上下文中使用,但我认为您可以看到问题。为什么这个计算是错误的?我该如何解决这个问题?

最佳答案

给定

a := StrToTime('7:00');
b := StrToTime('17:30');

ShowMessage(FloatToStr(a));
ShowMessage(FloatToStr(b));

您的代码使用 MinutesBetween 有效地执行了此操作:

ShowMessage(IntToStr(trunc(MinuteSpan(a, b)))); // Gives 629

但是,四舍五入可能会更好:

ShowMessage(IntToStr(round(MinuteSpan(a, b)))); // Gives 630

浮点值实际上是多少?

ShowMessage(FloatToStr(MinuteSpan(a, b))); // Gives 630

所以你显然在这里遇到了传统的浮点问题。

更新:

Round 的主要好处是,如果分钟跨度非常接近整数,则四舍五入的值将保证是该整数,而截断的值很可能是前面的整数。

Trunc 的主要好处是您可能实际上想要这种逻辑:事实上,如果您在五天内满 18 岁,从法律上讲您仍然不被允许申请瑞典驾驶执照。

因此,如果您想使用 Round 而不是 Trunc,您只需添加

function MinutesBetween(const ANow, AThen: TDateTime): Int64;
begin
Result := Round(MinuteSpan(ANow, AThen));
end;

到您的单位。那么标识符 MinutesBetween 将以相同的单位引用此标识符,而不是 DateUtils 中的标识符。一般规则是编译器将使用它最新找到的函数。因此,例如,如果您将此函数放在您自己的单元 DateUtilsFix 中,则

implementation

uses DateUtils, DateUtilsFix

将使用新的MinutesBetween,因为DateUtilsFix出现在DateUtils的右侧。

更新2:

另一种可行的方法可能是

function MinutesBetween(const ANow, AThen: TDateTime): Int64;
var
spn: double;
begin
spn := MinuteSpan(ANow, AThen);
if SameValue(spn, round(spn)) then
result := round(spn)
else
result := trunc(spn);
end;

如果跨度在整数的模糊范围内,则返回round(spn),否则返回trunc(spn)

例如,使用这种方法

07:00:00 and 07:00:58

将产生 0 分钟,就像原来的基于 trunc 的版本一样,也正如瑞典 Trafikverket 所希望的那样。但它不会受到引发OP问题的问题的影响。

关于delphi - 如何解决 Delphi 无法准确处理日期时间操作的问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15031706/

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