如何获取毫秒分辨率的 Windows 系统时间?
如何获取毫秒分辨率的 Windows 系统时间?
如果上述不可能,那么我怎样才能获取操作系统的启动时间呢?我想将此值与 timeGetTime() 一起使用,以计算毫秒分辨率的系统时间。
How can I get the Windows system time with millisecond resolution?
If the above is not possible, then how can I get the operating system start time? I would like to use this value together with timeGetTime()
in order to compute a system time with millisecond resolution.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
从 Windows 8 开始,Microsoft 引入了新的 API 命令
GetSystemTimePreciseAsFileTime
不幸的是,如果您创建的软件也必须在较旧的操作系统上运行,则无法使用它。
我目前的解决方案如下,但要注意:确定的时间并不准确,只是接近实时时间。结果应始终小于或等于实际时间,但具有固定误差(除非计算机进入待机状态)。结果具有毫秒分辨率。就我的目的而言,这已经足够准确了。
Starting with Windows 8 Microsoft has introduced the new API command
GetSystemTimePreciseAsFileTime
Unfortunately you can't use that if you create software which must also run on older operating systems.
My current solution is as follows, but be aware: The determined time is not exact, it is only near to the real time. The result should always be smaller or equal to the real time, but with a fixed error (unless the computer went to standby). The result has a millisecond resolution. For my purpose it is exact enough.
GetSystemTimeAsFileTime 提供最佳精度任何用于绝对时间的 Win32 函数。正如 Joel Clark 所建议的,QPF/QPC 将提供更好的相对时间。
GetSystemTimeAsFileTime gives the best precision of any Win32 function for absolute time. QPF/QPC as Joel Clark suggested will give better relative time.
由于我们来这里都是为了快速的片段而不是无聊的解释,所以我会写一个:
不知道基于性能计数器的答案是如何上升的,不要做滑点错误,伙计们。
Since we all come here for quick snippets instead of boring explanations, I'll write one:
No idea how drifting performance-counter-based answers went up, don't do slippage bugs, guys.
QueryPerformanceCounter()
专为细粒度计时器解析而构建。它是系统必须提供的最高分辨率计时器,您可以在应用程序代码中使用它来识别性能瓶颈。
这是 C# 开发人员的简单实现:
如果您是 C/C++ 开发人员,请查看此处:如何使用
QueryPerformanceCounter
Visual C++ 中对代码进行计时的函数QueryPerformanceCounter()
is built for fine-grained timer resolution.It is the highest resolution timer that the system has to offer that you can use in your application code to identify performance bottlenecks
Here is a simple implementation for C# devs:
If you are a C/C++ dev, then take a look here: How to use the
QueryPerformanceCounter
function to time code in Visual C++好吧,这个函数已经很老了,但 Windows C 库中还有另一个有用的函数
_ftime
,返回一个结构体,其中包含本地时间time_t
、毫秒、时区和夏令时标志。Well, this one is very old, yet there is another useful function in Windows C library
_ftime
, which returns a structure with local time astime_t
, milliseconds, timezone, and daylight saving time flag.在 C11 及更高版本(或 C++17 及更高版本)中,您可以使用
timespec_get ()
以可移植的方式获得更高精度的时间如果您使用的是 C++,那么从 C++11 开始,您可以使用
std::chrono::high_resolution_clock
,std::chrono::system_clock
(挂钟),或std::chrono::steady_clock
(单调时钟)在新的
标题。不再需要使用特定于 Windows 的 APIIn C11 and above (or C++17 and above) you can use
timespec_get()
to get time with higher precision portablyIf you're using C++ then since C++11 you can use
std::chrono::high_resolution_clock
,std::chrono::system_clock
(wall clock), orstd::chrono::steady_clock
(monotonic clock) in the new<chrono>
header. No need to use Windows-specific APIs anymore试试 MSDN 杂志上的这篇文章。实际上相当复杂。
为 Windows 实现持续更新的高分辨率时间提供程序
(存档链接)
Try this article from MSDN Magazine. It's actually quite complicated.
Implement a Continuously Updating, High-Resolution Time Provider for Windows
(archive link)
在 Windows 中,所有时间的基础是一个名为
GetSystemTimeAsFileTime
的函数。FILETIME
结构记录了自1600年1月1日以来100ns间隔的数量;这意味着它的分辨率被限制在100ns。这构成了我们的第一个函数:
自 1600 年 1 月 1 日以来的 100 纳秒刻度的 64 位数字有些难以处理。 Windows 提供了一个方便的辅助函数
FileTimeToSystemTime
,它可以将此 64 位整数解码为有用的部分:请注意,
SYSTEMTIME
具有1ms< 的内置分辨率限制。 /code>
现在我们有办法从
FILETIME
到SYSTEMTIME
:我们可以编写函数来获取当前系统时间作为
SYSTEIMTIME
结构:除了 Windows 已经为您编写了这样的函数:
GetSystemTime
本地时间,而不是 UTC
现在,如果您不希望当前时间为 UTC 格式,该怎么办?如果您想在当地时间怎么办? Windows 提供了将 UTC 格式的
FILETIME
转换为本地时间的函数:FileTimeToLocalFileTime
您可以编写一个返回 < 的函数code>FILETIME 在本地时间已经:
假设您要将本地 FILETIME 解码为 SYSTEMTIME。没问题,您可以再次使用
FileTimeToSystemTime
:幸运的是,Windows 已经为您提供了一个返回值的函数:
精确
有另一个考虑因素。在 Windows 8 之前,时钟的分辨率约为 15 毫秒。在 Windows 8 中,他们将时钟提高到 100ns(与
FILETIME
的分辨率相匹配)。GetSystemTimeAsFileTime
(传统,15ms 分辨率)GetSystemTimePreciseAsFileTime
(Windows 8,100ns 分辨率)这意味着我们应该始终更喜欢新值:
您询问了时间
您询问了时间;但你有一些选择。
时区:
格式:
FILETIME
(系统本机,100ns 分辨率)SYTEMTIME
(解码,1ms 分辨率)摘要
FILETIME
GetSytemTimePreciseAsFileTime
(或GetSystemTimeAsFileTime
)SYSTEMTIME< /代码>- UTC:
- 本地:
GetSystemTime
GetLocalTime
In Windows, the base of all time is a function called
GetSystemTimeAsFileTime
.The
FILETIME
structure records the number of 100ns intervals since January 1, 1600; meaning its resolution is limited to 100ns.This forms our first function:
A 64-bit number of 100ns ticks since January 1, 1600 is somewhat unwieldy. Windows provides a handy helper function,
FileTimeToSystemTime
that can decode this 64-bit integer into useful parts:Notice that
SYSTEMTIME
has a built-in resolution limitation of1ms
Now we have a way to go from
FILETIME
toSYSTEMTIME
:We could write the function to get the current system time as a
SYSTEIMTIME
structure:Except Windows already wrote such a function for you:
GetSystemTime
Local, rather than UTC
Now what if you don't want the current time in UTC. What if you want it in your local time? Windows provides a function to convert a
FILETIME
that is in UTC into your local time:FileTimeToLocalFileTime
You could write a function that returns you a
FILETIME
in local time already:And lets say you want to decode the local FILETIME into a SYSTEMTIME. That's no problem, you can use
FileTimeToSystemTime
again:Fortunately, Windows already provides you a function that returns you the value:
Precise
There is another consideration. Before Windows 8, the clock had a resolution of around 15ms. In Windows 8 they improved the clock to 100ns (matching the resolution of
FILETIME
).GetSystemTimeAsFileTime
(legacy, 15ms resolution)GetSystemTimePreciseAsFileTime
(Windows 8, 100ns resolution)This means we should always prefer the new value:
You asked for the time
You asked for the time; but you have some choices.
The timezone:
The format:
FILETIME
(system native, 100ns resolution)SYTEMTIME
(decoded, 1ms resolution)Summary
FILETIME
GetSytemTimePreciseAsFileTime
(orGetSystemTimeAsFileTime
)SYSTEMTIME
GetSystemTime
GetLocalTime
这是对上述评论的详细阐述,以解释其中的一些原因。
首先, GetSystemTime* 调用是唯一提供系统时间的 Win32 API。这次的粒度相当粗,因为大多数应用程序不需要维持更高分辨率所需的开销。时间(可能)在内部存储为 64 位毫秒计数。调用
timeGetTime
获取低位32位。调用 GetSystemTime 等请求 Windows 在转换为天等并包括系统启动时间后返回此毫秒时间。机器中有两个时间源:CPU 时钟和板载时钟(例如,实时时钟(RTC)、可编程间隔定时器(PIT)和高精度事件定时器(HPET))。第一个的分辨率约为 0.5ns (2GHz),第二个通常可编程至 1ms 的周期(尽管较新的芯片 (HPET) 具有更高的分辨率)。 Windows 使用这些周期性的滴答声来执行某些操作,包括更新系统时间。
应用程序可以通过 timerBeginPeriod;然而,这会影响整个系统。操作系统将按照请求的频率检查/更新常规事件。在低 CPU 负载/频率下,存在空闲期以节省电量。在高频率下,没有时间将处理器置于低功耗状态。请参阅计时器分辨率< /a> 了解更多详情。最后,每个时钟周期都有一些开销,增加频率会消耗更多的 CPU 周期。
对于更高分辨率的时间,系统时间无法保持到这种精度,就像大本钟没有秒针一样。使用
QueryPerformanceCounter
(QPC) 或CPU 的刻度(rdtsc
) 可以提供系统时间刻度之间的分辨率。 Kevin 引用的 MSDN 杂志文章中使用了这种方法。尽管这些方法可能存在漂移(例如,由于频率缩放)等,因此需要与系统时间同步。This is an elaboration of the above comments to explain the some of the whys.
First, the GetSystemTime* calls are the only Win32 APIs providing the system's time. This time has a fairly coarse granularity, as most applications do not need the overhead required to maintain a higher resolution. Time is (likely) stored internally as a 64-bit count of milliseconds. Calling
timeGetTime
gets the low order 32 bits. Calling GetSystemTime, etc requests Windows to return this millisecond time, after converting into days, etc and including the system start time.There are two time sources in a machine: the CPU's clock and an on-board clock (e.g., real-time clock (RTC), Programmable Interval Timers (PIT), and High Precision Event Timer (HPET)). The first has a resolution of around ~0.5ns (2GHz) and the second is generally programmable down to a period of 1ms (though newer chips (HPET) have higher resolution). Windows uses these periodic ticks to perform certain operations, including updating the system time.
Applications can change this period via timerBeginPeriod; however, this affects the entire system. The OS will check / update regular events at the requested frequency. Under low CPU loads / frequencies, there are idle periods for power savings. At high frequencies, there isn't time to put the processor into low power states. See Timer Resolution for further details. Finally, each tick has some overhead and increasing the frequency consumes more CPU cycles.
For higher resolution time, the system time is not maintained to this accuracy, no more than Big Ben has a second hand. Using
QueryPerformanceCounter
(QPC) or the CPU's ticks (rdtsc
) can provide the resolution between the system time ticks. Such an approach was used in the MSDN magazine article Kevin cited. Though these approaches may have drift (e.g., due to frequency scaling), etc and therefore need to be synced to the system time.GetTickCount
不会为您完成它。查看
QueryPerformanceFrequency
/QueryPerformanceCounter
。不过,这里唯一的问题是 CPU 扩展,所以请做好研究。GetTickCount
will not get it done for you.Look into
QueryPerformanceFrequency
/QueryPerformanceCounter
. The only gotcha here is CPU scaling though, so do your research.