Delphi 将时间添加到TDateTime

Delphi 将时间添加到TDateTime,delphi,Delphi,我想将秒添加到TDateTime变量中,这样结果就是分钟的顶端。例如,如果是08:30:25,我希望将TDateTime变量更改为存储08:31:00 我看到TDateTime有一个解码功能,我可以使用它。但是,没有一个编码函数可以将更改后的时间返回到TDateTime变量中。至少在最近的版本中,确实有,请参阅单元,尤其是所有的重新编码*例程和。Delphi 2010中已经提供了DateUtils装置,甚至可能在早期版本中也提供了。使用DateUtils可以这样做: Uses DateUti

我想将秒添加到
TDateTime
变量中,这样结果就是分钟的顶端。例如,如果是08:30:25,我希望将
TDateTime
变量更改为存储08:31:00


我看到
TDateTime
有一个解码功能,我可以使用它。但是,没有一个编码函数可以将更改后的时间返回到TDateTime变量中。

至少在最近的版本中,确实有,请参阅单元,尤其是所有的
重新编码*
例程和。Delphi 2010中已经提供了
DateUtils
装置,甚至可能在早期版本中也提供了。

使用
DateUtils
可以这样做:

Uses
  DateUtils;

var
  Seconds : Word;    

Seconds := SecondOfTheMinute(MyTime);  // Seconds from last whole minute
// Seconds := SecondOf(MyTime); is equivalent to SecondOfTheMinute()
if (Seconds > 0) then
  MyTime := IncSecond(MyTime,60 - Seconds);
理论
TDateTime
数据类型以实数形式表示自1899年12月30日以来的天数。也就是说,
TDateTime
的整数部分是整天的数量,小数部分表示一天中的某个时间

实用的 因此,您的问题可以使用简单的算法解决:

var
  Days: TDateTime;
  Mins: Extended;  { widen TDateTime's mantissa by 11 bits to accommodate division error } 

begin
  Days := Date + StrToTime('08:30:25');
  Writeln(DateTimeToStr(Days));


  Mins := Days * 24 * 60 ;  // compute minutes
  Mins := Math.Ceil(Mins);  // round them up
  Days := Mins / (24 * 60); // and back to days
  { or as simple and concise expression as: }
  // Days := Ceil(Days * MinsPerDay) / MinsPerDay;

  Writeln(DateTimeToStr(Days));

在旧版本中,可以使用EncodeDate(y,m,d)+EncodeTime(h,min,0,0)。DateUtils是旧单位,因为D6或更旧。但实际上并没有必要去做OP想要做的事情。Delphi5肯定没有(只是检查了一下)。无论如何,DateUtils中的函数允许以一种可读性很好的方式实现它,所以为什么不使用它呢。Delphi 7也进行了检查。示例中的最后一行不应该是:Mytime:=IncSecond(Mytime,60-Seconds)?我删除了您对“TDateTime实例”的引用,因为
TDateTime
不是类或记录,因此您不能拥有它的“实例”
TDateTime
只是一种类型,实际上是一种
Double
。要了解更一般的方法,请查看它,它允许您四舍五入到最近的分钟、四分之一小时、小时等。您的四舍五入规则非常模糊。08:30:25四舍五入到分钟将是08:30,而不是08:31。
TDateTime
的部分问题是双倍的,小数部分是一天中的时间。这意味着某些分钟不能表示为精确的数字。因此,较新的
DateUtils
库在进行计算之前,总是将小数部分转换为包含从午夜开始的一天毫秒数的整数64。因此,使用库函数比在
TDateTime
上进行显式计算更安全。“看,”戴维谢弗南,我看到了,也知道历史。我有一个数学函数,可以很好地解决这个问题。但精度总是有限制的,所以我没有发表它。我知道您将
TDateTime
上的任何数学运算称为
实现泄漏
,因为使用
TDateTime
不应该利用它作为
双精度实现的事实。我同意使用
DateUtils
SysUtils
是更好的选择。曾经有一段时间,
DateUtils
有很多错误,许多实现了自己的
TDateTime
utils。当时间不能用二进制浮点表示时,此代码可能会失败。构建一个失败的例子应该很容易。这将是一个已经有00秒的时间。但最接近的可表示值大于真实值。@David Heffernan,我不这么认为。如果它应该是如此简单-请回来与实际的例子失败。你知道的代表性和二进制浮点?它在粘贴箱。遗憾的是,您不了解代表性问题。你知道不是所有的实数都可以表示吗?您知道吗,表格
N/1440
中只有极少数数字是可以精确表示的?你如何解释我寄给你的pastebin的行为?或者,当你我意见不一致时,我总是错的,这是信仰的问题吗?即使证据不是这样说,“这是可以通过ε四舍五入修正的。”很高兴你终于面对了需要修正的事实。我不知道epsilon的事。我不知道你的意思。如果必须保持浮点,那么解决方法是:
Math.Ceil(dt1*24*60-0.25)/(24*60)
。这对6000年左右的人来说很好。那时我们可能还在争论。