随笔 - 2146  文章 - 19 评论 - 11846 阅读 - 1267万

//相关函数:
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
posted on   万一  阅读(5325)  评论(1编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
历史上的今天:
2008-05-22 WinAPI: InvertRect - 翻转矩形中像素的颜色
2008-05-22 WinAPI: OffsetRect - 移动矩形
2008-05-22 WinAPI: IntersectRect、SubtractRect、UnionRect - 用两个矩形合成一个新的矩形
2008-05-22 我是怎样给 Delphi 代码着色的 - 回复 "sunhj " 的问题
2008-05-22 把文字输出到屏幕


点击右上角即可分享
微信分享提示