SetSystemTimeAdjustmentPrecise 函数 (sysinfoapi.h)

启用或禁用对系统时间时钟的定期时间调整。 启用后,此类时间调整可用于将一天中的时间与某些其他时间源信息同步。

语法

BOOL SetSystemTimeAdjustmentPrecise(
  [in] DWORD64 dwTimeAdjustment,
  [in] BOOL    bTimeAdjustmentDisabled
);

参数

[in] dwTimeAdjustment

提供调整后的时钟更新频率。

[in] bTimeAdjustmentDisabled

提供一个标志,该标志指定系统要使用的时间调整模式。

值为 TRUE 表示系统应使用自己的内部机制同步一天中的时间。 在这种情况下, 将忽略 dwTimeAdjustment 的值。

值为 FALSE 表示应用程序处于控制状态,并且指定值 dwTimeAdjustment 将在每次时钟更新中断时添加到一天中的时间时钟。

返回值

如果函数成功,则返回值为非零。

如果函数失败,则返回值为零。 要获得更多的错误信息,请调用 GetLastError。 函数可能失败的一种方式是调用方没有SE_SYSTEMTIME_NAME特权。

注解

若要使用此函数,调用方必须具有系统时间特权 (SE_SYSTEMTIME_NAME) 。 默认情况下,此权限处于禁用状态。 使用 AdjustTokenPrivileges 函数在调用此函数之前启用特权,然后在函数调用后禁用该特权。 有关详细信息,请参阅下面的代码示例。

示例

此示例演示如何启用系统时间权限、使用 GetSystemTimeAdjustmentPreciseSetSystemTimeAdjustmentPrecise 调整系统时钟,以及如何整齐地打印当前系统时间调整。


/****************************************************************** 
* 
* ObtainRequiredPrivileges 
* 
* Enables system time adjustment privilege. 
* 
******************************************************************/ 
HRESULT 
ObtainRequiredPrivileges() 
{ 
    HRESULT hr; 
    HANDLE hProcToken = NULL; 
    TOKEN_PRIVILEGES tp = {0}; 
    LUID luid; 

    if (!LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME, &luid)) 
    { 
        hr = HRESULT_FROM_WIN32(GetLastError()); 
        printf("Failed to lookup privilege value. hr=0x%08x\n", hr); 
        return hr; 
    } 

    // get the token for our process 
    if (!OpenProcessToken(GetCurrentProcess(), 
    TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, 
    &hProcToken)) 
    { 
        hr = HRESULT_FROM_WIN32(GetLastError()); 
        printf("Failed to open process token. hr=0x%08x\n", hr); 
        return hr; 
    } 

    // Enable just the SYSTEMTIME privilege 
    tp.PrivilegeCount = 1; 
    tp.Privileges[0].Luid = luid; 
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 

    if (!AdjustTokenPrivileges(hProcToken, FALSE, &tp, 0, NULL, NULL)) 
    { 
        hr = HRESULT_FROM_WIN32(GetLastError()); 
        printf("Failed to adjust process token privileges. hr=0x%08x\n", hr); 
    } 
    else 
    { 
        hr = S_OK; 
        printf("Added SYSTEMTIME privilege to the process token\n"); 
    } 
    
    if (NULL != hProcToken) 
    { 
        CloseHandle(hProcToken); 
    } 
    return hr; 
} 

/****************************************************************** 
* 
* PrintCurrentClockAdjustments 
* 
* Prints current values of the system time adjustments. 
* 
******************************************************************/ 
void 
PrintCurrentClockAdjustments() 
{ 
    // More granular clock adjustments 
    DWORD64 ullCurrentAdjustment = 0; 
    DWORD64 ullTimeIncrement = 0; 
    BOOL bEnabledPrecise = 0; 
    HRESULT hrPrecise = S_OK; 

    // Legacy clock adjustments 
    DWORD dwCurrentAdjustment = 0; 
    DWORD dwTimeIncrement = 0; 
    BOOL bEnabled = 0; 
    HRESULT hr = S_OK; 

    if (!GetSystemTimeAdjustmentPrecise(&ullCurrentAdjustment, &ullTimeIncrement, &bEnabledPrecise)) 
    { 
        hrPrecise = HRESULT_FROM_WIN32(GetLastError()); 
    } 

    if (!GetSystemTimeAdjustment(&dwCurrentAdjustment, &dwTimeIncrement, &bEnabled)) 
    { 
        hr = HRESULT_FROM_WIN32(GetLastError()); 
    } 

    printf("Precise_ADJ:%I64u Precise_INCR:%I64u Precise_EN:%d Precise_hr:0x%08x ADJ:%u INCR:%u EN:%d hr:0x%08x\n", 
            ullCurrentAdjustment, ullTimeIncrement, bEnabledPrecise, hrPrecise, 
            dwCurrentAdjustment, dwTimeIncrement, bEnabled, hr); 
} 

/****************************************************************** 
* 
* RunNewAdjustmentSequence 
* 
* Adjust the system time using high-resolution 
* GetSystemTimeAdjustmentPrecise() and SetSystemTimeAdjustmentPrecise() API. 
* 
******************************************************************/ 
void 
RunNewAdjustmentSequence(DWORD dwPPMAdjustment) 
{ 
    DWORD64 ullCurrentAdjustment = 0; 
    DWORD64 ullTimeIncrement = 0; 
    BOOL bEnabledPrecise = 0; 
    LARGE_INTEGER liPerfCounterFrequency = {0}; 
    DWORD dwNewAdjustmentUnits; 
    const DWORD cMicroSecondsPerSecond = 1000000; 

    if (dwPPMAdjustment > 1000) 
    { 
        printf("Adjustment too large. Skipping new adjustment sequence.\n"); 
        return; 
    } 

    printf("Starting adjustment sequence using new API...\n"); 

    if (!GetSystemTimeAdjustmentPrecise(&ullCurrentAdjustment, &ullTimeIncrement, &bEnabledPrecise)) 
    { 
        printf("Failed to read the system time adjustment. Adjustment sequence aborted. hr:0x%08x\n", 
        HRESULT_FROM_WIN32(GetLastError())); 
        return; 
    } 

    (void)QueryPerformanceFrequency(&liPerfCounterFrequency); 
    printf("System Performance Counter Frequency: %I64u\n", 
    liPerfCounterFrequency.QuadPart); 


    dwNewAdjustmentUnits = (DWORD)(((float) dwPPMAdjustment * liPerfCounterFrequency.QuadPart/ cMicroSecondsPerSecond)); 

    printf("Adjusting the system clock by +%d PPM (+%d new units)\n", 
    dwPPMAdjustment, dwNewAdjustmentUnits); 

    if (!SetSystemTimeAdjustmentPrecise(ullCurrentAdjustment + dwNewAdjustmentUnits, FALSE)) 
    { 
        printf("Failed to set the system time adjustment. hr:0x%08x\n", 
        HRESULT_FROM_WIN32(GetLastError())); 
    } 

    PrintCurrentClockAdjustments(); 

    printf("Restoring system clock adjustment settings\n"); 

    if (!SetSystemTimeAdjustmentPrecise(ullCurrentAdjustment, FALSE)) 
    { 
        printf("Failed to set the system time adjustment. hr:0x%08x\n", 
        HRESULT_FROM_WIN32(GetLastError())); 
    } 

    PrintCurrentClockAdjustments(); 

    printf("Adjusting the system clock by -%d PPM (-%d new units)\n", 
    dwPPMAdjustment, dwNewAdjustmentUnits); 

    if (!SetSystemTimeAdjustmentPrecise(ullCurrentAdjustment - dwNewAdjustmentUnits, FALSE)) 
    { 
        printf("Failed to set the system time adjustment. hr:0x%08x\n", 
        HRESULT_FROM_WIN32(GetLastError())); 
    } 

    PrintCurrentClockAdjustments(); 

    printf("Restoring system clock adjustment settings\n"); 

    if (!SetSystemTimeAdjustmentPrecise(ullCurrentAdjustment, FALSE)) 
    { 
        printf("Failed to set the system time adjustment. hr:0x%08x\n", 
        HRESULT_FROM_WIN32(GetLastError())); 
    } 

    PrintCurrentClockAdjustments(); 

    printf("Adjustment sequence complete\n\n"); 
}

要求

   
最低受支持的客户端 Windows 10 [仅限桌面应用]
最低受支持的服务器 Windows Server 2016 [仅限桌面应用]
目标平台 Windows
标头 sysinfoapi.h
Library Mincore.lib
DLL Api-ms-win-core-version-l1-2-3.dll

另请参阅

GetSystemTimeAdjustmentPrecise