如何以毫秒级分辨率获得Windows系统时间?

axi*_*mar 20 windows time resolution system

如何以毫秒级分辨率获得Windows系统时间?

如果上述情况不可行,那么如何才能获得操作系统的启动时间?我想将此值与timeGetTime()一起使用,以便计算具有毫秒分辨率的系统时间.

先感谢您.

Kev*_*ale 21

试试MSDN杂志上的这篇文章.这实际上非常复杂.

为Windows实施不断更新的高分辨率时间提供程序

  • 你读过这篇文章了吗?那是什么意思!这个人完全按照你的要求做了,并展示了它是如何完成的,包括代码. (3认同)
  • 这个链接为我而死.http://web.archive.org/web/2012101806540​​3/http://msdn.microsoft.com/en-us/magazine/cc163996.aspx (2认同)

Bri*_*ian 11

这是对上述评论的详细说明,以解释其中的一些原因.

首先,GetSystemTime*调用是唯一提供系统时间的Win32 API.这个时间具有相当粗略的粒度,因为大多数应用程序不需要维持更高分辨率所需的开销.时间(可能)在内部存储为64位毫秒计数.调用timeGetTime获得低位32位.调用GetSystemTime等请求Windows返回此毫秒时间,转换为天后等,并包括系统启动时间.

机器中有两个时间源:CPU的时钟和板载时钟(例如,实时时钟(RTC),可编程间隔定时器(PIT)和高精度事件定时器(HPET)).第一个的分辨率约为0.5ns(2GHz),第二个通常可编程为1ms(尽管较新的芯片(HPET)具有更高的分辨率).Windows使用这些定期滴答来执行某些操作,包括更新系统时间.

应用程序可以通过timerBeginPeriod更改此期间; 但是,这会影响整个系统.操作系统将以请求的频率检查/更新常规事件.在低CPU负载/频率下,存在节省功率的空闲时段.在高频率下,没有时间将处理器置于低功耗状态.见计时器分辨率为进一步的细节.最后,每个tick都有一些开销,增加频率会消耗更多的CPU周期.

对于更高分辨率的时间,系统时间不能保持这种精度,不会超过大本钟的秒针.使用QueryPerformanceCounter(QPC)或CPU的ticks(rdtsc)可以提供系统时间标记之间的分辨率.这种方法被用于MSDN杂志文章凯文所引用的文章中.虽然这些方法可能具有漂移(例如,由于频率缩放)等,因此需要与系统时间同步.


Joe*_*ark 7

GetTickCount 不会为你完成它.

看看QueryPerformanceFrequency/ QueryPerformanceCounter.这里唯一的问题是CPU扩展,你的研究也是如此.


Ian*_*oyd 7

在Windows中,所有时间的基础是一个称为的函数GetSystemTimeAsFiletime

  • 它返回一个结构,该结构能够保留100ns重新设定时间。
  • 它保存在UTC中

FILETIME结构记录了自1600年1月1日以来的100ns间隔数。表示其分辨率限制为100ns。

这形成了我们的第一个功能:

在此处输入图片说明

自1600年1月1日以来,100ns滴答声的64位数字有些笨拙。Windows提供了一个方便的帮助程序功能,FileTimeToSystemTime可以将这个64位整数解码为有用的部分:

record SYSTEMTIME {
   wYear: Word;
   wMonth: Word;
   wDayOfWeek: Word;
   wDay: Word;
   wHour: Word;
   wMinute: Word;
   wSecond: Word;
   wMilliseconds: Word;
}
Run Code Online (Sandbox Code Playgroud)

请注意,SYSTEMTIME内置分辨率限制为1ms

现在,我们有一条路要走FILETIMESYSTEMTIME

在此处输入图片说明

我们可以编写函数以获取当前系统时间为SYSTEIMTIME结构:

SYSTEMTIME GetSystemTime()
{
    //Get the current system time utc in it's native 100ns FILETIME structure
    FILETIME ftNow;
    GetSytemTimeAsFileTime(ref ft);

    //Decode the 100ns intervals into a 1ms resolution SYSTEMTIME for us
    SYSTEMTIME stNow;
    FileTimeToSystemTime(ref stNow);

    return stNow;
}
Run Code Online (Sandbox Code Playgroud)

除了Windows已经为您编写了这样的功能: GetSystemTime

在此处输入图片说明

本地而不是UTC

现在,如果您不希望使用UTC的当前时间怎么办。如果您想在当地时间怎么办?Windows提供了将FILETIMEUTC时间转换为本地时间的功能:FileTimeToLocalFileTime

在此处输入图片说明

您可以编写一个已经FILETIME本地时间返回a的函数:

FILETIME GetLocalTimeAsFileTime()
{
   FILETIME ftNow;
   GetSystemTimeAsFileTime(ref ftNow);

   //convert to local
   FILETIME ftNowLocal
   FileTimeToLocalFileTime(ftNow, ref ftNowLocal);

   return ftNowLocal;
}
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

并说您想将本地 FILETIME 解码为SYSTEMTIME。没问题,您可以FileTimeToSystemTime再次使用:

在此处输入图片说明

幸运的是,Windows已经为您提供了一个返回值的函数:

在此处输入图片说明

精确

还有另一个考虑。在Windows 8之前,时钟的分辨率约为15ms。在Windows 8中,他们将时钟提高到100ns(与的分辨率匹配FILETIME)。

  • GetSystemTimeAsFileTime (旧版,15ms分辨率)
  • GetSystemTimeAsPreciseFileTime (Windows 8,100ns分辨率)

这意味着我们应该始终偏爱新值:

在此处输入图片说明

你问时间

您要求时间;但是你有一些选择。

时区:

  • UTC (系统本机)
  • 当地时区

格式:

  • FILETIME (系统本机,100ns分辨率)
  • SYTEMTIME (已解码,分辨率为1ms)

摘要

  • 100ns解析度: FILETIME
    • UTC :(GetSytemTimeAsPreciseFileTime GetSystemTimeAsFileTime
    • 本地:(自行滚动)
  • 1ms分辨率: SYSTEMTIME
    • 世界标准时间: GetSystemTime
    • 本地: GetLocalTime