«текущий» время, возвращаемое различными функциями Windows, не всегда подсчитывается со скоростью 60 секунд каждый раз.
Иногда Windows намеренно имеет часы происходит немного медленнее, или немного быстрее:
- Если ваши часы PC в настоящее время за текущий правильное время: работать чуть быстрее догнать
- Если ваши часы PC в настоящее время опережает текущее Corret время: работать немного медленнее , чтобы позволить правильное время догнать этот
Он делает это вместо того, чтобы иметь ваши часы внезапно JUMP, и теперь ваши лог-файлы имеют временные аномалии.
Вы можете использовать GetSystemTimeAdjustment
, чтобы увидеть, если Windows, в настоящее время отсчитывают ваши часы быстрее или медленнее или по номинальной ставке. Например, на моем компьютере прямо сейчас:
- System Time Установка: Disabled
- Добавление номинальной 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 никогда не ускоряется и не замедляется. Он всегда рассчитывается с точностью до 60 с/мин.
| 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
будет оба:
- быть синхронизированы
- быть в пределах нескольких десятых доли микросекунды каждого другого
- имеет конечное разрешение 100 нса (0.1 us)
Для точного измерения времени это две функции, которые вы должны использовать. Вопрос, какой из них вы заботитесь для выполнения этой задачи:
бонуса болтовня
Это должно быть отметил, что структура SYSTEM_TIME
возвращается GetLocalTime
и GetSystemTime
по своей сути ограничены точностью в миллисекундах. Там нет никакого способа для GetSystemTime
, чтобы дать вам разрешение суб-миллисекунды, просто потому, что тип возвращаемого значения не имеет места, чтобы дать вам микросекунд:
struct SYSTEMTIME {
WORD wYear;
WORD wMonth;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds; //<---- that's the limit
}
Вы должны использовать только SYSTEM_TIME
, когда вы хотите Windows, чтобы сломать время для вас вниз, лет, месяцев, дней, часов, минут, секунд. С другой стороны, структура FILE_TIME
является максимальной точностью 100ns (0,1 us).
Точные временные функции
В языке я использую, мы используем DateTime
, что является плавающей точкой а Double
точности, где:
- целой часть представляет собой количество дней с момента 12/30/1899
- дробная часть представляет собой часть 24-часовой день
Это схема даты и времени используется по COM, OLE, Delphi, VB, Excel, Lotus 123; и аналогично схеме datetime, используемой 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;
}