gpt4 book ai didi

c++ - 在 Windows C++ 中使用具有毫秒精度和分辨率的时间戳记录

转载 作者:可可西里 更新时间:2023-11-01 12:47:06 26 4
gpt4 key购买 nike

我知道对于计时准确性而言,timeGetTime、timeBeginPeriod、QueryPerformanceCounter 等函数非常棒,可以提供良好的分辨率和准确性,但仅基于自启动后的时间,与时钟时间没有直接链接。

但是,我不想这样计时事件。我希望能够生成一个准确的时间戳(本地时间),以便我可以在日志文件中显示它,例如 31-12-2010 12:38:35.345,用于每个条目。 (我需要毫秒精度)

标准的 Windows 时间函数,如 GetLocalTime,虽然它们提供毫秒值,但没有毫秒分辨率,具体取决于运行的操作系统。我使用的是 XP,所以我不能期望比大约 15 毫秒的分辨率更好。

我需要的是一种既能两全其美又不会产生大量开销来获得所需输出的方法。过大的方法/计算意味着记录器在其操作期间会开始消耗太多时间。

最好/最简单的方法是什么?

最佳答案

首先是一些函数:

// ==========================================================================
#define NOMINMAX
#define _AFXDLL
#include "afxwin.h" // TRACE
#include "windows.h" // ULARGE_INTEGER
#include "mmSystem.h" // timeGetTime
#pragma comment(lib, "Winmm.lib") // timeGetTime

// ==========================================================================
// convert FILETIME to ULONGLONG
// (casting won't work on 64-bit platforms, due to alignment of FILETIME members)
inline void ToULL(const FILETIME& ft, ULONGLONG& uft)
{
ULARGE_INTEGER uli;
uli.LowPart = ft.dwLowDateTime ;
uli.HighPart= ft.dwHighDateTime;
uft= uli.QuadPart;
}

// --------------------------------------------------------------------------
// convert ULONGLONG to FILETIME
// (casting won't work on 64-bit platforms, due to alignment of FILETIME members)
inline void ToFILETIME(const ULONGLONG& uft, FILETIME& ft)
{
ULARGE_INTEGER uli;
uli.QuadPart= uft;
ft.dwLowDateTime = uli.LowPart ;
ft.dwHighDateTime= uli.HighPart;
}

// --------------------------------------------------------------------------
// ULONGLONG version for GetSystemTimeAsFileTime
inline void GetSystemTimeAsULL(ULONGLONG& uft)
{
FILETIME ft;
::GetSystemTimeAsFileTime(&ft);
ToULL(ft, uft);
}

// --------------------------------------------------------------------------
// convert ULONGLONG to time-components
bool ULLToSystemTime(const ULONGLONG nTime , // [i]
WORD& nYear , // [o] 1601 - 30827
WORD& nMonth , // [o] 1 - 12
WORD& nDay , // [o] 1 - 31
WORD& nHour , // [o] 0 - 23
WORD& nMinute , // [o] 0 - 59
WORD& nSecond , // [o] 0 - 59
WORD& nMilliseconds ) // [o] 0 - 999
{
SYSTEMTIME sysTime;
FILETIME ft ;
ToFILETIME(nTime, ft);

// the wDayOfWeek member of the SYSTEMTIME structure is ignored
if (0 == ::FileTimeToSystemTime(&ft, &sysTime))
return false;

nYear = sysTime.wYear ;
nMonth = sysTime.wMonth ;
nDay = sysTime.wDay ;
nHour = sysTime.wHour ;
nMinute = sysTime.wMinute ;
nSecond = sysTime.wSecond ;
nMilliseconds= sysTime.wMilliseconds;
return true;
}

// --------------------------------------------------------------------------
void TraceTime(const ULONGLONG nTime) // [i]
{
WORD nYear,nMonth,nDay,nHour,nMinute,nSecond,nMilliseconds;
ULLToSystemTime(nTime, nYear,nMonth,nDay,nHour,nMinute,nSecond,nMilliseconds);
TRACE("Time: %02u-%02u-%04u %02u:%02u:%02u.%03u\n", nDay,nMonth,nYear,nHour,nMinute,nSecond,nMilliseconds);
}

现在,如何使用:

ULONGLONG u0,u1;
::GetSystemTimeAsULL(u0);

// wait for tick (each 14.4mS)
do
{
::GetSystemTimeAsULL(u1);
}
while (u0==u1);

DWORD d1= ::timeGetTime();

// d1 and u1 are now synchronized

// ... do some work

// get current time:
ULONGLONG u2= u1+(::timeGetTime() - d1)*10000; // mSec --> HectoNanoSec

TraceTime(u2);

请注意,您应该在 2-3 分钟内重新同步一次 d1 和 u1 以保持准确性。实际上,您可以测量时钟之间的漂移以找到最佳的重新同步间隔。

关于c++ - 在 Windows C++ 中使用具有毫秒精度和分辨率的时间戳记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4570194/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com