//相关函数: SysUtils.DateTimeToFileDate(); SysUtils.FileDateToDateTime(); SysUtils.DateTimeToSystemTime(); SysUtils.SystemTimeToDateTime(); Windows.SystemTimeToFileTime(); Windows.FileTimeToSystemTime(); Windows.FileTimeToDosDateTime(); Windows.DosDateTimeToFileTime(); Windows.FileTimeToLocalFileTime(); Windows.LocalFileTimeToFileTime(); Windows.GetLocalTime();
//TSystemTime 是系统定义的结构, 一看就是最方便实用的那种, 但要占 16 个字节: TSystemTime = record wYear: Word; wMonth: Word; wDayOfWeek: Word; wDay: Word; wHour: Word; wMinute: Word; wSecond: Word; wMilliseconds: Word; end; //TFileTime 也是系统定义的结构, 同 TDateTime 一样大小, 但结构原理完全不同: TFileTime = record dwLowDateTime: DWORD; dwHighDateTime: DWORD; end; TFileTime 记录的是从 1601-1-1 起的时间值, 以 100 纳秒(也就是万分之一毫秒)为单位 //DOS 时间就是一个 32 位(4字节)的整数(Integer), 好像没有专门的结构, 可用 LongRec 等代为解析. DOS 时间的尺寸是 TFileTime、TDateTime 的 1/2, 是 TSystemTime 的 1/4; 因此不很精确. 它只能表示从 1980-2107 之间的时间, 且只能精确到 2 秒.
//下面几个函数一看就知道谁转换到谁: SysUtils.DateTimeToSystemTime(); SysUtils.SystemTimeToDateTime(); Windows.SystemTimeToFileTime(); Windows.FileTimeToSystemTime(); Windows.FileTimeToDosDateTime(); Windows.DosDateTimeToFileTime(); //但并没有直接给 TFileTime 和 TDateTime 直接转换的函数; //下面两个函数是 TDateTime 和 DOS 时间的转换; 文件的创建、修改、访问时间就是用这个 DOS 时间记录的. SysUtils.DateTimeToFileDate(); SysUtils.FileDateToDateTime(); {转换到 DOS 时间的例子:} var T: TDateTime; F,DosTime: Integer; FileTime: TFileTime; SystemTime: TSystemTime; begin {构建一个 TDateTime, 并转换到 DOS 时间} T := EncodeDateTime(2009, 5, 22, 11, 22, 33, 999); F := DateTimeToFileDate(T); ShowMessage(IntToStr(F)); //985029328; 注意这个数很小, 下面会发现不精确 {再从 DOS 时间转回 TDateTime} T := FileDateToDateTime(F); ShowMessage(FormatDateTime('yyyy-m-d h:m:s:zzz', T)); //2009-5-22 11:22:32:000; 只精确到 2 秒 {TDateTime -> TSystemTime -> TFileTime -> DOS 时间} DateTimeToSystemTime(T, SystemTime); SystemTimeToFileTime(SystemTime, FileTime); FileTimeToDosDateTime(FileTime, LongRec(DosTime).Hi, longRec(DosTime).Lo); ShowMessage(IntToStr(SizeOf(SystemTime))); //985029328; 和上面得到的值一样 end;
DateTimeToFileDate 转换出的时间不是 TFileTime, 而是 Dos 时间或叫文件时间;
譬如我们用 FileAge 函数返回的文件最后修改的时间(一个 Integer)就是个 Dos 时间.
{读取记事本程序最后被修改的时间} var DosTime: Integer; FileTime: TFileTime; SysTime: TSystemTime; DateTime: TDateTime; str: string; begin DosTime := FileAge('C:\Windows\System32\Notepad.exe'); ShowMessage(IntToStr(DosTime)); //948804037; 这是读取结果 {转换为可以理解的格式} DosDateTimeToFileTime(LongRec(DosTime).Hi, LongRec(DosTime).Lo, FileTime); FileTimeToSystemTime(FileTime, SysTime); str := Format('%d年%d月%d日 %d:%d:%d', [SysTime.wYear, SysTime.wMonth, SysTime.wDay, SysTime.wHour, SysTime.wMinute, SysTime.wSecond]); ShowMessage(str); //2008年4月13日 19:14:10 {如果仅仅是要这个时间, 可以这样} FileAge('C:\Windows\System32\Notepad.exe', DateTime); ShowMessage(DateTimeToStr(DateTime)); //2008-4-13 19:14:10 end;
又是我们可能只需要一个 TSystemTime 格式的时间, 没必要转来转去, 可以直接用 GetLocalTime 函数获取:
var SysTime: TSystemTime; DT1, DT2: TDateTime; begin GetLocalTime(SysTime); DT1 := SystemTimeToDateTime(SysTime); DT2 := Now; {这两个时间显示应该是一样的} ShowMessage(DateTimeToStr(DT1)); ShowMessage(DateTimeToStr(DT2)); end;
另外 FileTimeToLocalFileTime 和 LocalFileTimeToFileTime 是本地时间和 UTC(国际标准计时) 的转换;
用 API 函数获取的 TFileTime 时间都是 UTC 格式的, 需要转换使用.
DateUtils-Function