从GetSystemTimePreciseAsFileTime()到本地时间的可靠快速方式

时间:2017-06-02 10:48:24

标签: c++ winapi time timezone localtime

WinAPI函数GetSystemTimePreciseAsFileTime()将时间写入FILETIME结构,该时间为UTC。我想以微秒和百纳秒获得当地时间。我希望这个算法首先是可靠的,然后是快速的。

问题是我到目前为止所考虑的所有WinAPI似乎都不可靠:

  1. FileTimeToLocalFileTime()似乎不可靠,因为its documentation
  2.   

    考虑将文件时间转换为a时的夏令时   当地时间,使用以下功能序列代替使用   FileTimeToLocalFileTime ...

    1. 但是,上述序列函数SystemTimeToTzSpecificLocalTime()中的建议似乎也不可靠,因为its documentation说:
    2.   

      SystemTimeToTzSpecificLocalTime函数可以计算本地   在以下情况下时间不正确:

           

      a)时区使用a   新旧年份的不同UTC偏移量。

           

      b)UTC时间   转换和计算的当地时间是不同的年份。

      案例a)似乎并不重要,但是,我绝对希望算法能够在新年前正常运作。

      最后,我考虑了SystemTimeToTzSpecificLocalTimeEx(),但是,我不清楚它与SystemTimeToTzSpecificLocalTime()有什么不同,而且它的文档似乎不值得信赖:它说lpTimeZoneInformation参数是是可选的,但它没有说明如何指定默认值(是NULL?)以及该函数在该默认情况下的行为(它会假设当前时区吗?)。

      算法的下一部分是提取亚毫秒值,因为SYSTEMTIME结构不提供它们。我可以采用N%10000,其中N是存储在uint64_t结构中的FILETIME值吗?

1 个答案:

答案 0 :(得分:2)

SystemTimeToTzSpecificLocalTimeSystemTimeToTzSpecificLocalTimeEx之间的区别在于后者使用DYNAMIC_TIME_ZONE_INFORMATION结构,该结构正确反映了Windows注册表中的所有年度信息。

TIME_ZONE_INFORMATION结构对时区信息进行任何逐年更改。它只反映当前的活跃规则。如果您正在处理任意日期时间值,则应避免使用此结构,因为您无法保证当前规则是您正在使用的日期时间的正确规则。

但是,如果您关心的只是当前时间,那么就没有必要关注自己的年度变化。即使您在一年的开始或结束时间,Windows也会在适当的时间更新当前时区规则。

此外,对于SystemTimeToTzSpecificLocalTimeSystemTimeToTzSpecificLocalTimeEx函数,时区参数是可选的。传递NULL将使用当前的本地时区。这在SystemTimeToTzSpecificLocalTime

中有记录
  

如果lpTimeZoneNULL,则该功能会使用当前有效的时区。

SystemTimeToTzSpecificLocalTimeEx上的文档遗漏了它,但效果相同。

因此,要获得操作系统可以提供的所有可用精度的当前本地时间,请:

  1. GetSystemTimePreciseAsFileTime
  2. FileTimeToSystemTime
  3. SystemTimeToTzSpecificLocalTime(此处不需要Ex,并保留tz null)
  4. SystemTimeToFileTime
  5. 从步骤1复制到亚毫秒,再到步骤4的结果。