「當前」由各種Windows功能返回的時間並不總是每次以60秒的速率計數。
有時的Windows 故意已經時鐘會稍微慢一點,還是有點快:
- 如果您的PC時鐘是目前當前正確的時間背後:運行稍快趕上
- 如果您的PC時鐘是目前領先的當前corret時間:運行稍微慢到讓正確的時間趕上這個
它這樣做,而不是讓你的時鐘突然JUMP,現在你的日誌文件有時間異常。
您可以使用GetSystemTimeAdjustment
來看看Windows正在滴答作響目前您的時鐘快或慢,或者名義利率。例如,現在我的電腦上:
- 系統時間調整:殘疾人
- 添加標稱15,6250毫秒每次更新
但是如果你的時鐘是太遠離正確的時間,Windows將只是BONK你的時間到了正確的時間。
時間可以跑,快,慢,前進,後退。 QueryPerformanceCounter的將不
因此,通過返回的時間:
| Function | Return type | Resolution | Timezone |
|--------------------------------|-------------------|------------|----------|
| GetLocalTime | SYSTEM_TIME (1ms) | ~10-15 ms | Local |
| GetSystemTime | SYSTEM_TIME (1ms) | ~10-15 ms | UTC |
| GetSystemTimeAsFileTime | FILE_TIME (0.1us) | ~10-15 ms | UTC |
| GetSystemTimeAsPreciseFileTime | FILE_TIME (0.1us) | 0.1 us | UTC |
所有能跑得快,慢,或跳躍,爲您的時鐘跳動。雖然QueryPerformanceCounter永遠不會加快或放慢速度。它始終以60s/min的速率正好計數。
| Function | Return type | Resolution | Timezone |
|--------------------------------|-------------------|------------|----------|
| GetLocalTime | SYSTEM_TIME (1ms) | ~10-15 ms | Local |
| GetSystemTime | SYSTEM_TIME (1ms) | ~10-15 ms | UTC |
| GetSystemTimeAsFileTime | FILE_TIME (0.1us) | ~10-15 ms | UTC |
| GetSystemTimeAsPreciseFileTime | FILE_TIME (0.1us) | 0.1 us | UTC |
| | | | |
| GetTickCount | Int32 (1ms) | ~10-15 ms | n/a |
| GetTickCount64 | Int64 (1ms) | ~10-15 ms | n/a |
| QueryPerformanceCounter | Int64 (ticks) | 0.1 us | n/a |
那麼你關心
只要您的計算機的時鐘沒有目前正在進行SystemTimeAdjustment
,經過間隔由測量:
- GetSytemTimeAsPreciseFileTime
- QueryPerformanceCounter的
將兩者:
- 保持同步
- 是彼此
- 一微秒的十分之幾內具有爲100ns(0最終分辨率。1 us)
對於精確的時間測量,這些是您應該使用的兩個功能。你關心的任務,一個問題,:
加成顫振基準標記
測量持續時間高分辨率測量
它應該是注意到由GetLocalTime
返回的SYSTEM_TIME
結構和GetSystemTime
固有地限於毫秒精度。有沒有辦法讓GetSystemTime
給你亞毫秒級的分辨率,完全是因爲返回類型沒有地方給你微秒:
struct SYSTEMTIME {
WORD wYear;
WORD wMonth;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds; //<---- that's the limit
}
當你想讓Windows下到打破時間,你應該只使用SYSTEM_TIME
年,月,日,小時,分鐘,秒。另一方面,FILE_TIME
結構的最終精度爲100ns(0.1 us)。
精確時間函數
在我使用的語言中,我們使用一個DateTime
這是一個Double
精度浮點,其中:
- 整數部分表示自12/30/1899的天數
- 分數部分表示一天24小時的一小部分
這是所使用的日期時間方案通過COM,OLE,Delphi,VB,Excel,Lotus 123;並類似於SQL Server使用的日期時間方案(儘管它們使用1/1/1900而不是12/30/1899)
DateTime UtcNowPrecise()
{
const UInt64 OA_ZERO_TICKS = 94353120000000000; //12/30/1899 12:00am in ticks
const UInt64 TICKS_PER_DAY = 864000000000; //ticks per day
FILE_TIME ft;
GetSystemTimePreciseAsFileTime(out ft);
ULARGE_INTEGER dt; //needed to avoid alignment faults
dt.LowPart = ft.dwLowDateTime;
dt.HighPart = ft.dwHighDateTime;
return (dt.QuadPart - OA_ZERO_TICKS)/TICKS_PER_DAY;
}
DateTime NowPrecise()
{
const UInt64 OA_ZERO_TICKS = 94353120000000000; //12/30/1899 12:00am in ticks
const UInt64 TICKS_PER_DAY = 864000000000; //ticks per day
FILE_TIME ft;
GetSystemTimePreciseAsFileTime(out ft);
//Convert from UTC to local
FILE_TIME ftLocal;
if (!FileTimeToLocalFileTime(ft, ref ftLocal))
RaiseLastNativeError();
ULARGE_INTEGER dt; //needed to avoid alignment faults
dt.LowPart = ftLocal.dwLowDateTime;
dt.HighPart = ftLocal.dwHighDateTime;
return (dt.QuadPart - OA_ZERO_TICKS)/TICKS_PER_DAY;
}