C++设置系统时间的几种方式 Windows 11 C++设置系统时间需要管理员权限。判断是否为管理员并切换Run as administrator SYSTEMTIME时间+8小时变为本地时间同步

C++设置系统时间的几种方式 Windows 11 C++设置系统时间需要管理员权限。判断是否为管理员并切换Run as administrator SYSTEMTIME时间+8小时变为本地时间同步

Windows 11 C++设置系统时间

在Windows 11中,使用C++设置系统时间需要管理员权限。设置系统时间涉及修改操作系统的关键参数,为了防止未经授权的修改,Windows要求进行这些操作的用户拥有管理员权限。

在C++中,设置系统时间可以通过调用Windows API函数SetSystemTime来实现。然而,在调用这个函数之前,必须确保程序以管理员身份运行,否则会失败并返回权限不足的错误。

示例代码

以下是一个使用SetSystemTime函数设置系统时间的简单示例:

#include

#include

int main() {

// 创建一个SYSTEMTIME结构体,并设置时间

SYSTEMTIME st;

st.wYear = 2024;

st.wMonth = 6;

st.wDay = 4;

st.wHour = 12;

st.wMinute = 0;

st.wSecond = 0;

st.wMilliseconds = 0;

// 设置系统时间

if (SetSystemTime(&st)) {

std::cout << "系统时间设置成功。" << std::endl;

} else {

std::cout << "系统时间设置失败。" << std::endl;

}

return 0;

}

提升权限

为了以管理员身份运行程序,可以在程序的属性中设置,也可以在代码中检查并请求管理员权限。以下是一个简单的实现方法,通过创建一个新的进程以管理员权限重新运行自己:

#include

#include

#include

bool IsRunAsAdministrator() {

BOOL isElevated = FALSE;

HANDLE token = nullptr;

if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) {

TOKEN_ELEVATION elevation;

DWORD size;

if (GetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation), &size)) {

isElevated = elevation.TokenIsElevated;

}

CloseHandle(token);

}

return isElevated;

}

void ElevateToAdministrator() {

char path[MAX_PATH];

GetModuleFileName(NULL, path, ARRAYSIZE(path));

SHELLEXECUTEINFO sei = { sizeof(sei) };

sei.lpVerb = "runas";

sei.lpFile = path;

sei.hwnd = NULL;

sei.nShow = SW_NORMAL;

if (!ShellExecuteEx(&sei)) {

DWORD dwError = GetLastError();

if (dwError == ERROR_CANCELLED) {

std::cerr << "用户取消了提升操作。" << std::endl;

}

}

}

int main() {

if (!IsRunAsAdministrator()) {

std::cout << "程序未以管理员身份运行。尝试提升权限..." << std::endl;

ElevateToAdministrator();

return 0;

}

SYSTEMTIME st;

st.wYear = 2024;

st.wMonth = 6;

st.wDay = 4;

st.wHour = 12;

st.wMinute = 0;

st.wSecond = 0;

st.wMilliseconds = 0;

if (SetSystemTime(&st)) {

std::cout << "系统时间设置成功。" << std::endl;

} else {

std::cout << "系统时间设置失败。" << std::endl;

}

return 0;

}

这个示例代码首先检查程序是否以管理员身份运行。如果不是,则尝试重新启动自己并请求管理员权限。如果用户接受了权限提升请求,程序将以管理员身份重新启动,并设置系统时间。

C++设置系统时间的几种方式

在Windows 11上,用C++代码设置系统时间可以通过多种方式实现。下面是一些常见的方法:

使用SetLocalTime API:使用SetSystemTime API:调用命令行工具 w32tm:调用命令行工具 date 和 time:

每种方法的具体实现如下:

方法 1: 使用 SetLocalTime API

SetLocalTime 设置本地时间(即系统时区下的时间)。

#include

#include

bool SetLocalSystemTime(int year, int month, int day, int hour, int minute, int second) {

// Initialize SYSTEMTIME structure

SYSTEMTIME st;

GetLocalTime(&st); // Get current local time

st.wYear = year;

st.wMonth = month;

st.wDay = day;

st.wHour = hour;

st.wMinute = minute;

st.wSecond = second;

st.wMilliseconds = 0; // Optional: can be set to 0

// Set the new local system time

if (!SetLocalTime(&st)) {

std::cerr << "Failed to set local system time. Error: " << GetLastError() << std::endl;

return false;

}

return true;

}

int main() {

int year = 2024;

int month = 6;

int day = 4;

int hour = 12;

int minute = 30;

int second = 0;

if (SetLocalSystemTime(year, month, day, hour, minute, second)) {

std::cout << "Local system time set successfully." << std::endl;

} else {

std::cerr << "Failed to set local system time." << std::endl;

}

return 0;

}

方法 2: 使用 SetSystemTime API

SetSystemTime 设置UTC时间(协调世界时),在大多数情况下需要转换为本地时间后使用。

#include

#include

bool SetSystemTimeUTC(int year, int month, int day, int hour, int minute, int second) {

// Initialize SYSTEMTIME structure

SYSTEMTIME st;

GetSystemTime(&st); // Get current system time

st.wYear = year;

st.wMonth = month;

st.wDay = day;

st.wHour = hour;

st.wMinute = minute;

st.wSecond = second;

st.wMilliseconds = 0; // Optional: can be set to 0

// Set the new system time (UTC)

if (!SetSystemTime(&st)) {

std::cerr << "Failed to set system time (UTC). Error: " << GetLastError() << std::endl;

return false;

}

return true;

}

int main() {

int year = 2024;

int month = 6;

int day = 4;

int hour = 12;

int minute = 30;

int second = 0;

if (SetSystemTimeUTC(year, month, day, hour, minute, second)) {

std::cout << "System time (UTC) set successfully." << std::endl;

} else {

std::cerr << "Failed to set system time (UTC)." << std::endl;

}

return 0;

}

方法 3: 调用命令行工具 w32tm

使用C++代码调用系统命令行工具 w32tm 来设置时间。

#include

#include // for system()

bool SyncSystemTimeWithW32tm() {

// Construct the command to sync system time using w32tm

const char* command = "w32tm /resync";

// Execute the command

int result = system(command);

if (result != 0) {

std::cerr << "Failed to sync system time using w32tm. Error code: " << result << std::endl;

return false;

}

return true;

}

int main() {

if (SyncSystemTimeWithW32tm()) {

std::cout << "System time synced successfully using w32tm." << std::endl;

} else {

std::cerr << "Failed to sync system time using w32tm." << std::endl;

}

return 0;

}

方法 4: 调用命令行工具 date 和 time

使用C++代码调用 date 和 time 命令来设置系统日期和时间。

#include

#include // for system()

bool SetSystemDateAndTime(const std::string& date, const std::string& time) {

// Construct the command to set the date

std::string dateCommand = "date " + date;

std::string timeCommand = "time " + time;

// Execute the date command

int resultDate = system(dateCommand.c_str());

if (resultDate != 0) {

std::cerr << "Failed to set system date. Error code: " << resultDate << std::endl;

return false;

}

// Execute the time command

int resultTime = system(timeCommand.c_str());

if (resultTime != 0) {

std::cerr << "Failed to set system time. Error code: " << resultTime << std::endl;

return false;

}

return true;

}

int main() {

std::string date = "06-04-24"; // MM-DD-YY format

std::string time = "12:30:00"; // HH:MM:SS format

if (SetSystemDateAndTime(date, time)) {

std::cout << "System date and time set successfully." << std::endl;

} else {

std::cerr << "Failed to set system date and time." << std::endl;

}

return 0;

}

注意事项

权限:更改系统时间需要管理员权限。确保运行这些程序时使用管理员权限。时区:SetLocalTime 和 SetSystemTime 的主要区别是时区。使用 SetSystemTime 时,你需要处理UTC时间。安全:更改系统时间可能会影响系统的其他服务和功能,请谨慎使用。

通过以上方法,你可以在Windows 11上使用C++代码设置系统时间。选择最适合你需求的方法来实现。

时区 本地时间+8

要将 SYSTEMTIME 结构中的时间增加8小时(例如,从UTC时间转换为中国标准时间(CST)),可以使用以下步骤:

将 SYSTEMTIME 转换为 FILETIME。使用 ULARGE_INTEGER 结构增加8小时的时间。将 FILETIME 转换回 SYSTEMTIME。

下面是具体的实现代码:

#include

#include

void AddHoursToSystemTime(SYSTEMTIME& st, int hours) {

// Convert SYSTEMTIME to FILETIME

FILETIME ft;

SystemTimeToFileTime(&st, &ft);

// Convert FILETIME to ULARGE_INTEGER

ULARGE_INTEGER li;

li.LowPart = ft.dwLowDateTime;

li.HighPart = ft.dwHighDateTime;

// Add hours (converted to 100-nanosecond intervals)

li.QuadPart += static_cast(hours) * 60 * 60 * 10000000;

// Convert back to FILETIME

ft.dwLowDateTime = li.LowPart;

ft.dwHighDateTime = li.HighPart;

// Convert FILETIME back to SYSTEMTIME

FileTimeToSystemTime(&ft, &st);

}

int main() {

// Initialize SYSTEMTIME with some UTC time

SYSTEMTIME st;

st.wYear = 2024;

st.wMonth = 6;

st.wDay = 4;

st.wHour = 12;

st.wMinute = 30;

st.wSecond = 0;

st.wMilliseconds = 0;

std::cout << "Original UTC time: "

<< st.wYear << "-" << st.wMonth << "-" << st.wDay << " "

<< st.wHour << ":" << st.wMinute << ":" << st.wSecond << std::endl;

// Add 8 hours to convert to local time

AddHoursToSystemTime(st, 8);

std::cout << "Local time (UTC+8): "

<< st.wYear << "-" << st.wMonth << "-" << st.wDay << " "

<< st.wHour << ":" << st.wMinute << ":" << st.wSecond << std::endl;

return 0;

}

解释

SYSTEMTIME到FILETIME的转换:使用 SystemTimeToFileTime 函数将 SYSTEMTIME 转换为 FILETIME。FILETIME到ULARGE_INTEGER的转换:因为 FILETIME 由两个32位值组成,使用 ULARGE_INTEGER 可以方便地进行加法操作。添加小时数:将小时数转换为100纳秒的间隔进行加法操作。1小时=3600秒,1秒=10000000个100纳秒单位。转换回SYSTEMTIME:将修改后的 FILETIME 转换回 SYSTEMTIME。

通过这种方式,你可以将 SYSTEMTIME 结构中的时间增加8小时,转换为本地时间(如UTC+8的中国标准时间)。

同步时间

从服务器获取时间 TCP连接后会自动收到4字节,倒序即为时间戳,自动断开TCP。如果不稳定,就多找几个ip轮循。

比如: TCP 128.138.141.172:37 科罗拉多大学博尔德分校 美国 科罗拉多州 博尔德

使用

if (GetPrivateProfileInt("CFG_FILE", "EnableSyncPCTime", YES, configFileName))//同步PC时间

{

logger.INFO_F("查询当前是否以管理员运行");

if (!IsRunAsAdministrator()) {

logger.INFO_F("程序未以管理员身份运行。尝试提升权限...");

ElevateToAdministrator();

logger.Close();

exit(0);

}

else { logger.INFO_F("当前为管理员运行模式"); }

pWnd->ShowInfo("开始同步PC时间,请等待");

Sleep(100);

while(TRUE)

{

if (DEF_SYNDATETIME_SUCCESS == SYNServerDateTime())

{

SYSTEMTIME st;

CHAR temp[64] = { 0 };

GetLocalTime(&st);

//sprintf(temp, "2000010203040506"); //test

sprintf(temp, "%04d年%02d月%02d日 %02d时%02d分%02d秒", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);

pWnd->ShowInfo("同步PC时间:PASS "+CString(temp));

break;

}

else

{

AfxMessageBox("同步PC时间:FAIL "+CString(logger.errMessage.c_str()) + " 点OK重试");

}

}

}

else { logger.INFO_F("同步PC时间:关"); }

#include "ServerDateTime.h"

#include "winsock2.h"

#pragma comment(lib, "WS2_32.lib") // 显式连接套接字库

#include"utility.h"

#include "./pch.h"

#define TIME_SERVER_IP "128.138.141.172"

static WORD g_SYNDateTime = DEF_SYNDATETIME_ERROR;

SYSTEMTIME FormatServerTime(DWORD serverTime);

DWORD GetTimeFromServer(char *ip_addr);

void AddHoursToSystemTime(SYSTEMTIME& st, int hours) {

// Convert SYSTEMTIME to FILETIME

FILETIME ft;

SystemTimeToFileTime(&st, &ft);

// Convert FILETIME to ULARGE_INTEGER

ULARGE_INTEGER li;

li.LowPart = ft.dwLowDateTime;

li.HighPart = ft.dwHighDateTime;

// Add hours (converted to 100-nanosecond intervals)

li.QuadPart += static_cast(hours) * 60 * 60 * 10000000;

// Convert back to FILETIME

ft.dwLowDateTime = li.LowPart;

ft.dwHighDateTime = li.HighPart;

// Convert FILETIME back to SYSTEMTIME

FileTimeToSystemTime(&ft, &st);

}

WORD SYNServerDateTime2()

{

DWORD dwTime = 0;

SYSTEMTIME st;

dwTime = GetTimeFromServer(TIME_SERVER_IP);

if (dwTime == 0)

{

g_SYNDateTime = DEF_SYNDATETIME_ERROR;

return g_SYNDateTime;

}

st = FormatServerTime(dwTime);

// 校时 本机

if (SetSystemTime(&st))

{

printf("SetSystemTime set successfully.\n");

}

else {

g_SYNDateTime = DEF_SYNDATETIME_ERROR;

printf("Failed to set SetSystemTime. 必须以管理员方式运行\n");

return g_SYNDateTime;

}

CString m_Time;

m_Time.Format(_T("格林尼治时间为:%d年%d月%d日%d时%d分%d秒%d\n"), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);

printf(m_Time);

AddHoursToSystemTime(st, 8);

//if (SetLocalTime(&st)) // 用这个差八小时

//{

// printf("SetLocalTime set successfully.\n");

//}

//else {

// printf("Failed to set SetLocalTime.\n");

//}

m_Time.Format(_T("北京时间为:%d年%d月%d日%d时%d分%d秒%d\n"), st.wYear, st.wMonth, st.wDay, st.wHour , st.wMinute, st.wSecond, st.wMilliseconds);

printf(m_Time);

g_SYNDateTime = DEF_SYNDATETIME_SUCCESS;

return g_SYNDateTime;

}

WORD SYNServerDateTime()

{

for(int i=0;i<10;i++)

{

if (SYNServerDateTime2() == DEF_SYNDATETIME_SUCCESS) { return g_SYNDateTime; }

Sleep(10);

}

return g_SYNDateTime;

}

WORD GetDateAndTime(BYTE *pbDate, BYTE *pbTime)

{

CString m_strDate;

CString m_strTime;

CString m_strDateTime;

BYTE pbTmp[32];

if (g_SYNDateTime== DEF_SYNDATETIME_SUCCESS)

{

CTime m_time;

m_time = CTime::GetCurrentTime(); //获取当前时间日期

//m_strDate = m_time.Format("%x"); //格式化日期

//m_strTime = m_time.Format("%X"); //格式化时间

//m_strDateTime = m_time.Format("%Y-%m-%d %H:%M:%S %A"); //格式化日期时间

m_strDate = m_time.Format("%Y%m%d");

m_strTime = m_time.Format("%H%M%S");

memset(pbTmp, 0x00, sizeof(pbTmp));

sprintf((char *)pbTmp, "%s", m_strDate);

StrToHex(pbDate, (char*)pbTmp, strlen((char *)pbTmp)/2);

memset(pbTmp, 0x00, sizeof(pbTmp));

sprintf((char *)pbTmp, "%s", m_strTime);

StrToHex(pbTime, (char*)pbTmp, strlen((char *)pbTmp)/2);

}

return g_SYNDateTime;

}

//从服务器获取时间 返回0错误

DWORD GetTimeFromServer(char *ip_addr)

{

// 参数ip_addr:表示指定的时间服务器IP地址

// 返回:自1900年1月1日午0时0分0秒至今的毫秒数 或 0(表示获取失败)

// 默认的时间服务器为"国家授时中心"

if (ip_addr == NULL)

{

ip_addr = _T(TIME_SERVER_IP);

}

// 定义WSADATA结构体对象

WSADATA date;

// 定义版本号码

WORD w = MAKEWORD(2, 0);

// 初始化套接字库

if (::WSAStartup(w, &date) != 0)

{

logger.ERROR_F("初始化套接字库失败!");

return 0;

}

// 定义连接套接字句柄

SOCKET s;

// 定义接收信息保存变量

DWORD m_serverTime;

// 创建TCP套接字

s = ::socket(AF_INET, SOCK_STREAM, 0);

if (INVALID_SOCKET == s)

{

logger.ERROR_F("创建套接字失败!");

// 关闭套接字句柄

::closesocket(s);

// 释放套接字库

::WSACleanup();

return 0;

}

// 定义套接字地址结构

sockaddr_in addr;

// 初始化地址结构

addr.sin_family = AF_INET;

addr.sin_port = htons(37);

addr.sin_addr.S_un.S_addr = inet_addr(ip_addr);

// 连接

if (::connect(s, (sockaddr*)&addr, sizeof(addr)) != 0)

{

int errorCode = ::WSAGetLastError();

switch (errorCode)

{

case 10060:

logger.ERROR_F("连接超时! " + to_string(errorCode));

break;

case 10051:

case 10065:

logger.ERROR_F("网络不可达! " + to_string(errorCode));

break;

default:

logger.ERROR_F("WSAGetLastError(): "+to_string(errorCode));

}

// 关闭套接字句柄

::closesocket(s);

// 释放套接字库

::WSACleanup();

return 0;

}

// 接收

if (::recv(s, (char *)&m_serverTime, 4, MSG_PEEK) <= 0)

{

logger.ERROR_F("接收错误!WSAGetLastError(): "+to_string( ::WSAGetLastError()));

// 关闭套接字句柄

::closesocket(s);

// 释放套接字库

::WSACleanup();

return 0;

}

// 关闭套接字句柄

::closesocket(s);

// 释放套接字库

::WSACleanup();

logger.INFO_F("获取服务器时间成功!" + bytesToHexString((BYTE*)&m_serverTime, 4));

// 网络字节顺序转换为主机字节顺序 倒过来

m_serverTime = ::ntohl(m_serverTime);

// 返回接收到的数据

return m_serverTime;

}

//格式化时间

SYSTEMTIME FormatServerTime(DWORD serverTime)

{

FILETIME ftNew;

SYSTEMTIME stNew;

stNew.wYear = 1900;

stNew.wMonth = 1;

stNew.wDay = 1;

stNew.wHour = 0;

stNew.wMinute = 0;

stNew.wSecond = 0;

stNew.wMilliseconds = 0;

::SystemTimeToFileTime(&stNew, &ftNew);

/* 将SYSTEMTIME结构设定为1900年1月1日午夜(0时)。

并将这个SYSTEMTIME结构传递给SystemTimeToFileTime,将此结构转化为FILETIME结构。

FILETIME实际上只是由两个32位元的DWORD一起组成64位元的整数,

用来表示从1601年1月1日至今间隔为100奈秒(nanosecond)的间隔数。 */

LARGE_INTEGER li; //64位大整数

li = *(LARGE_INTEGER *)&ftNew;

li.QuadPart += (LONGLONG)10000000 * serverTime;

ftNew = *(FILETIME *)&li;

::FileTimeToSystemTime(&ftNew, &stNew);

// 返回时间(注意:这里返回的是格林尼治时间,与北京时间相差8小时)

return stNew;

}

头文件

#ifndef _SERVER_DATE_TIME_H_

#define _SERVER_DATE_TIME_H_

#include

#define DEF_SYNDATETIME_SUCCESS (1)

#define DEF_SYNDATETIME_ERROR (0)

//1、同步服务器时间到本机PC

WORD SYNServerDateTime();

//1操作是否成功

//WORD GetSynDateTimeStatus();

//2、如果1成功,从本机获取时间

WORD GetDateAndTime(BYTE *pbDate,BYTE *pbTime);

#endif /**/

设置时间测试示例

#include

#include

#include

#include

void AddHoursToSystemTime(SYSTEMTIME& st, int hours) {

// Convert SYSTEMTIME to FILETIME

FILETIME ft;

SystemTimeToFileTime(&st, &ft);

// Convert FILETIME to ULARGE_INTEGER

ULARGE_INTEGER li;

li.LowPart = ft.dwLowDateTime;

li.HighPart = ft.dwHighDateTime;

// Add hours (converted to 100-nanosecond intervals)

li.QuadPart += static_cast(hours) * 60 * 60 * 10000000;

// Convert back to FILETIME

ft.dwLowDateTime = li.LowPart;

ft.dwHighDateTime = li.HighPart;

// Convert FILETIME back to SYSTEMTIME

FileTimeToSystemTime(&ft, &st);

}

bool SetSystemTime(int year, int month, int day, int hour, int minute, int second) {

// Initialize SYSTEMTIME structure

SYSTEMTIME st;

GetSystemTime(&st); // Get current system time

st.wYear = year;

st.wMonth = month;

st.wDay = day;

st.wHour = hour;

st.wMinute = minute;

st.wSecond = second;

st.wMilliseconds = 0; // Optional: can be set to 0

// Set the new system time

if (!SetSystemTime(&st)) {

std::cerr << "Failed to set system time. Error: " << GetLastError() << std::endl;

return false;

}

return true;

}

bool SetLocalSystemTime(int year, int month, int day, int hour, int minute, int second) {

// Initialize SYSTEMTIME structure

SYSTEMTIME st;

GetLocalTime(&st); // Get current local time

st.wYear = year;

st.wMonth = month;

st.wDay = day;

st.wHour = hour;

st.wMinute = minute;

st.wSecond = second;

st.wMilliseconds = 0; // Optional: can be set to 0

// Set the new local system time

if (!SetLocalTime(&st)) {

std::cerr << "Failed to set local system time. Error: " << GetLastError() << std::endl;

return false;

}

return true;

}

int main() {

int year = 2011;

int month = 11;

int day = 11;

int hour = 11;

int minute = 11;

int second = 11;

if (SetLocalSystemTime(year, month, day, hour, minute, second)) {

std::cout << "Local system time set successfully." << std::endl;

}

else {

std::cerr << "Failed to set local system time." << std::endl;

}

std::cin;

getchar();

SYSTEMTIME st;

st.wYear = 2012;

st.wMonth = 12;

st.wDay = 12;

st.wHour = 12;

st.wMinute = 12;

st.wSecond = 12;

st.wMilliseconds = 0;

AddHoursToSystemTime(st, -8);

if (SetSystemTime(st.wYear,st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond)) {

std::cout << "SetSystemTime set successfully." << std::endl;

}

else {

std::cerr << "Failed to set SetSystemTime." << std::endl;

}

std::cin;

getchar();

return 0;

}

相关推荐

365体育app官方下载 微盘如何搜索想要的资源 新浪微盘搜索文件资源教程
365体育app官方下载 笔记本的这些指示灯你认识几个? 笔记本指示灯详细介绍
365体育app官方下载 详细步骤教你如何快速注销百度账号