我知道,对于计时准确性,timeGetTime,timeBeginPeriod,Query
PerformanceCounter等功能都很棒,同时具有良好的分辨率和优点.准确性,但仅基于启动时间,没有与时钟时间的直接链接.
但是,我不想这样的时间事件.我希望能够生成一个确切的时间戳(本地时间),以便我可以在日志文件中显示它,例如31-12-2010 12:38:35.345,对于每个条目. (我需要毫秒精度)
标准的Windows时间函数,如GetLocalTime,虽然它们提供毫秒值,但没有毫秒级的分辨率,具体取决于运行的操作系统.我正在使用XP,所以我不能指望比大约15ms的分辨率好多了.
我需要的是一种获得两全其美的方法,而不会产生大量开销来获得所需的输出.过大的方法/计算意味着记录仪在其运行期间会开始耗费太多时间.
最好/最简单的方法是什么?
首先,一些功能:
原文链接:https://www.f2er.com/windows/365244.html// ========================================================================== #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,nMilliseconds); TRACE("Time: %02u-%02u-%04u %02u:%02u:%02u.%03u\n",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一次,以保持准确性.实际上,您可以测量时钟之间的漂移,以找到最佳的重新同步间隔.