如何以微秒精度将Delphi TDateTime转换为String

nfc*_*fc1 4 delphi datetime

我需要一个转换TDateTimeString微秒精度。在毫秒精度的情况下,可以使用格式设置:

DateTimeToString(Result, 'd.m.yyyy hh:nn:ss.zzz', dateTime);
Run Code Online (Sandbox Code Playgroud)

但是我还需要三位数(微秒)。

可以采用小数部分并将其除以1/86400/1000000,但我正在寻找更有效的方法进行转换。

Ian*_*oyd 5

日期时间的准确度取决于您距“零”的距离。

Delphi TDateTime实际上是8字节的浮点Double,零是12/31/1899 12:00:00 am

我们可以TDateTime通过将浮点日期时间增加最小可能的量来确定a的精度:

function AddQuantumToDateTime(const dt: TDateTime): TDateTime;
var
   overlay: Int64 absolute Result;
begin
   Result := dt;
   overlay := overlay+1;
end;
Run Code Online (Sandbox Code Playgroud)

这样,我们可以算出一个TDateTime罐子甚至可以处理的最小增量。它随使用日期的不同而变化,因为您离零越远,量子量就越大:

  • 1899年12月31日:0 ns
  • 1900年1月1日:0 ns
  • 1970年1月1日:314 ns
  • 2000年1月1日:629 ns
  • 1/1/2016:629纳秒
  • 1/1/2038:629 ns
  • 1/1/3000:5,029 ns
  • 1/1/4000:10,058 ns
  • 1/1/5000:20,117 ns
  • 1/1/6000:20,117 ns
  • 1/1/7000:20,117 ns
  • 1/1/8000:40,233 ns
  • 1/1/9000:40,233 ns
  • 1/1/9999:40,233 ns

因此,目前,DateTime 可以为您提供大约半微秒的分辨率。

尽管Windows FILETIME结构确实支持100ns的分辨率,但SYSTEMTIME结构仅支持低至毫秒的时间

typedef struct _SYSTEMTIME {
  WORD wYear;
  WORD wMonth;
  WORD wDayOfWeek;
  WORD wDay;
  WORD wHour;
  WORD wMinute;
  WORD wSecond;
  WORD wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME;
Run Code Online (Sandbox Code Playgroud)

Microsoft SQL Server的新datetime2(7)返回日期时间字符串,其秒精度最高为七位数(100 ns):

SELECT CAST('20160802' AS datetime2(6)) AS TheNow

TheNow
==========================
2016-08-02 00:00:00.000000
Run Code Online (Sandbox Code Playgroud)

然后,您的问题是如何将a转换为TDateTime包含微秒(十亿分之一秒)精度的字符串。您已经有了答案:

function DateTimeToStrUs(dt: TDatetime): string;
var
    us: string;
begin
    //Spit out most of the result: '20160802 11:34:36.'
    Result := FormatDateTime('yyyymmdd hh":"nn":"ss"."', dt);

    //extract the number of microseconds    
    dt := Frac(dt); //fractional part of day
    dt := dt * 24*60*60; //number of seconds in that day
    us := IntToStr(Round(Frac(dt)*1000000));

    //Add the us integer to the end:
    // '20160801 11:34:36.' + '00' + '123456'
    Result := Result + StringOfChar('0', 6-Length(us)) + us;
end;
Run Code Online (Sandbox Code Playgroud)

哪里:

DateTimeToStrUs(Now)
Run Code Online (Sandbox Code Playgroud)

返回值:

20160802 11:34:36.482364