zoukankan      html  css  js  c++  java
  • 时间与相关类型(3): TFileTime、TSystemTime 及 DOS 时间

    //相关函数:
    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
  • 相关阅读:
    【Redis】集群NetCore实战
    【Redis】集群教程(Windows)
    【Redis】入门
    【SQL SERVER】索引
    【SQL SERVER】锁机制
    【SQL SERVER】数据内部存储结构简单探索
    Windows软件包管理工具
    Git常用命令记录
    【ASP.NET Core学习】远程过程调用
    CouchDB学习-API
  • 原文地址:https://www.cnblogs.com/del/p/1487368.html
Copyright © 2011-2022 走看看