c++ - 从 GetSystemTimePreciseAsFileTime() 到本地时间的可靠快速方法

标签 c++ winapi time timezone localtime

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

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

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

To account for daylight saving time when converting a file time to a local time, use the following sequence of functions in place of using FileTimeToLocalFileTime...

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

The SystemTimeToTzSpecificLocalTime function may calculate the local time incorrectly under the following conditions:

a) The time zone uses a different UTC offset for the old and new years.

b) The UTC time to be converted and the calculated local time are in different years.

情况 a) 似乎并不重要,但是,我绝对希望该算法能在新年前后正常工作。

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

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

最佳答案

SystemTimeToTzSpecificLocalTimeSystemTimeToTzSpecificLocalTimeEx 之间的区别是后者使用了 DYNAMIC_TIME_ZONE_INFORMATION 结构,它正确地反射(reflect)了所有年同比来自 Windows 注册表的信息。

TIME_ZONE_INFORMATION 结构对时区信息有任何同比变化。它仅反射(reflect)当前事件规则。如果您使用任意日期时间值,则应避免使用此结构,因为您无法保证当前规则是您正在使用的日期时间的正确规则。

但是,如果您关心的只是当前时间,那么就没有必要关心年复一年的变化。即使您得到的时间接近年初或年底,Windows 也会在适当的时间更新当前时区规则。

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

If lpTimeZone is NULL, the function uses the currently active time zone.

SystemTimeToTzSpecificLocalTimeEx 上的文档中缺少它,但效果相同。

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

  1. GetSystemTimePreciseAsFileTime
  2. 文件时间到系统时间
  3. SystemTimeToTzSpecificLocalTime(此处不需要Ex,并保留 tz 为空)
  4. 系统时间到文件时间
  5. 将第 1 步的亚毫秒复制到第 4 步的结果。

关于c++ - 从 GetSystemTimePreciseAsFileTime() 到本地时间的可靠快速方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44327091/

相关文章:

c - 禁用 Windows CE 上的电源按钮

c - 如何将返回的WndProc/DlgProc句柄转换为函数地址?

php - 我怎样才能使这个 mysqli 查询在 PHP 中运行得更快?

mysql - 如何在Mysql中执行time_to_month?

javascript - 同时执行 JS 函数

c++ - 如何防止 COM Server EXE 打开命令提示符窗口

c++ - C++ 中的 vector 形状光栅化

c++ - 'make install' 被认为是有害的吗?

c++ - 具有用户定义的字符串文字的底层字符数据的存储持续时间

winapi - 如何检测系统中是否存在默认记录设备?