为什么DateUtils.pas中的DateTimeToMilliseconds被标记为内部函数?

4
为什么DateUtils.pas中的DateTimeToMilliseconds标记为internal?我能使用它吗?
{ Internal, converts a date-time to milliseconds }
function DateTimeToMilliseconds(const ADateTime: TDateTime): Int64;
var
  LTimeStamp: TTimeStamp;
begin
  LTimeStamp := DateTimeToTimeStamp(ADateTime);
  Result := LTimeStamp.Date;
  Result := (Result * MSecsPerDay) + LTimeStamp.Time;
end;
< p >【Delphi XE】


我在About.com上找到了这个:

经验表明,使用函数EncodeDateTime创建两个TDateTime值,它们之间仅相差一个毫秒时,函数返回的MillisecondsBetween并不像预期的那样返回,证明其不准确。

因此,如果我不关心几毫秒,我应该使用它。


2
你使用的 Delphi 版本是什么?DateUtils 单元在 XE 中进行了重大改版,使得这些函数在毫秒级别上都非常准确。 - Nick Hodges
我有 Delphi XE 专业版 - Gabriel
那篇About.com的文章涉及Delphi的旧版本 - 我看不到日期,但可能是Delphi 7。如果你按照其中的链接,最终会进入一个QC报告,展示你引用作为修复的精确代码!如上所述,它已经被添加到Delphi中,由@NickHodges和我下面所指出。 - David
2个回答

7
TDateTime 是一个浮点数。为了最小化计算 TDateTime 值时的舍入误差,DateUtils 中的大多数计算都将 TDateTime 转换为毫秒。
���后当计算准备就绪时,Int64 值会再次转换回 TDateTime 值。 internal 标记是为了强调该函数是实现细节,不应在库外部使用。也就是说,在处理 TDateTime 值时,请使用公共函数/过程。
下面是对 MilliSecondsBetween 函数的简单测试:
program TestMSecBetween;
{$APPTYPE CONSOLE}

uses 
  System.SysUtils,System.DateUtils;

var
  d1,d2 : TDateTime;
  i,iSec,iMin,iHour,iMSec;
  isb : Int64;
begin
  d1 := EncodeDateTime(2013,6,14,0,0,0,0);
  for i := 0 to 1000*60*60*24-1 do
  begin
    iHour := (i div (1000*60*60)) mod 24;
    iMin := (i div (1000*60)) mod 60;
    iSec := (i div 1000) mod 60;
    iMSec := i mod 1000;
    d2 := EncodeDateTime(2013,6,14,iHour,iMin,iSec,iMSec);
    isb := MilliSecondsBetween(d2,d1);
    if (isb <> i) then
      WriteLn(i:10,iHour:3,iMin:3,iSec:3,iMSec:4,isb:3);
  end;
  ReadLn;
end.

你可以延长测试时间来观察是否有异常情况。

3
若需要更多信息,请参阅此Delphi.about.com文章 ,其中提到了此方法的来源,即John Herbster的提案,旨在改善日期/时间方法的精度。如果您想要使用此方法,请创建一个本地副本,不要因为这样的小问题而编辑原始的DateUtils.pas文件。 - David
经验表明,使用函数EncodeDateTime创建两个相距仅一毫秒的TDateTime值时,该函数返回的MillisecondsBetween值并非预期结果,证明其不够准确。因此,如果我不在意几毫秒,我可以使用它吗? - Gabriel
你可以复制这个函数并使用它,没错。但首先请确保真的有必要。与TDateTime值一起工作的大多数实用方法都应该被SysUtils和DateUtils所覆盖。 - LU RD
1
请注意,自Delphi-2009(我想)以来,DateUtils计算的准确性得到了改善(很大程度上是由John Herbster的工作所贡献)。 - LU RD
1
@NickHodges 是正确的,Delphi-XE 有改进的 DateUtils 库。这里也可以找到它: DateUtils.pas - LU RD

1

你完全可以使用它,因为它没有被弃用且在内部使用。

只是因为函数头不在接口部分,所以标记为“内部”。如果将头文件复制到接口部分,它应该可以工作。

如果我们像这样“修补”第三方单元,我们总是将其复制到自己的搜索路径中的目录(命名为PatchLibs)中进行修改。这样,你就不会“损坏”原始文件,并且你也不必担心如何重建原始单元。


不要为了这么小的事情编辑VCL / RTL源代码!你应该非常谨慎地编辑VCL源代码 - 你会错过更新和补丁,并可能导致兼容性问题。只有在其他方式无法解决的重大重要错误修复时才进行编辑。对于像这样的事情,只需将方法复制到其他位置即可。 - David

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接