Windows下C语言API修改系统时间,附自动校准时间源码

发布于 / C语言 / Comments Off on Windows下C语言API修改系统时间,附自动校准时间源码

C语言Windows时钟的结构体如下:

typedef struct _SYSTEMTIME {  
  WORD wYear;              /*年*/  
  WORD wMonth;             /*月*/  
  WORD wDayOfWeek;         /*星期  0-6  0-Sunday...*/  
  WORD wDay;               /*日*/  
  WORD wHour;              /*时*/  
  WORD wMinute;            /*分*/  
  WORD wSecond;            /*秒*/  
  WORD wMilliseconds;      /*微妙*/  
} SYSTEMTIME, *PSYSTEMTIME;

获取时间的API为

void WINAPI GetLocalTime(  
  _Out_  LPSYSTEMTIME lpSystemTime  
);

设置时间的API为

BOOL WINAPI SetLocalTime(  
  _In_  const SYSTEMTIME *lpSystemTime  
);

下面这个函数可以用来修改系统时间,切记运行的时候一定要选择以管理员身份运行

(源码来自http://blog.csdn.net/embedded_sky/article/details/45059323

/* 
* @function : 设置Windows本地时间 
* @author   : super_bert 
* @in       : time_string - 14字节时间字符串(such as 20150415093000) 
* @return   : 0 - success 
*            -1 - failure 
**/  
int set_local_time(const char *time_string)  
{  
    SYSTEMTIME system_time = {0};  
    char year[4 + 1] = {0};  
    char month[2 + 1] = {0};  
    char day[2 + 1] = {0};  
    char hour[2 + 1] = {0};  
    char minute[2 + 1] = {0};  
    char second[2 + 1] = {0};  
    int index = 0;  
  
    strncpy(year, time_string + index, 4);  
    index += 4;  
    strncpy(month, time_string + index, 2);  
    index += 2;  
    strncpy(day, time_string + index, 2);  
    index += 2;  
    strncpy(hour, time_string + index, 2);  
    index += 2;  
    strncpy(minute, time_string + index, 2);  
    index += 2;  
    strncpy(second, time_string + index, 2);  
    index += 2;  
  
    GetLocalTime(&system_time);  
  
    system_time.wYear = atoi(year);  
    system_time.wMonth = atoi(month);  
    system_time.wDay = atoi(day);  
    system_time.wHour = atoi(hour);  
    system_time.wMinute = atoi(minute);  
    system_time.wSecond = atoi(second);  
  
    if (0 == SetLocalTime(&system_time))  
    {  
        return -1;  
    }  
          
    return 0;  
}

这里提供一个授时API

api地址:http://api.mmuaa.com/gettime

返回类型:#年月日小时分钟秒

例如#20171022230308

下面这个程序可以满足同步系统时间

#include  <stdio.h>
#include  <winsock.h>
#include  <string.h>
#pragma comment(lib, "ws2_32.lib")

int set_local_time(const char *time_string)  
{  
    SYSTEMTIME system_time = {0};  
    char year[4 + 1] = {0};  
    char month[2 + 1] = {0};  
    char day[2 + 1] = {0};  
    char hour[2 + 1] = {0};  
    char minute[2 + 1] = {0};  
    char second[2 + 1] = {0};  
    int index = 0;  
    strncpy(year, time_string + index, 4);  
    index += 4;  
    strncpy(month, time_string + index, 2);  
    index += 2;  
    strncpy(day, time_string + index, 2);  
    index += 2;  
    strncpy(hour, time_string + index, 2);  
    index += 2;  
    strncpy(minute, time_string + index, 2);  
    index += 2;  
    strncpy(second, time_string + index, 2);  
    index += 2;  
    GetLocalTime(&system_time);  
    system_time.wYear = atoi(year);  
    system_time.wMonth = atoi(month);  
    system_time.wDay = atoi(day);  
    system_time.wHour = atoi(hour);  
    system_time.wMinute = atoi(minute);  
    system_time.wSecond = atoi(second);  
    if (!SetLocalTime(&system_time))  
        return 0;  
    return 1;  
}  


bool geturl(char *url) {
  WSADATA WSAData= {0};
  SOCKET  sockfd;
  struct sockaddr_in  addr;
  struct hostent  *pURL;
  char  myurl[BUFSIZ];
  char  *pHost = 0, *pGET = 0;
  char  host[BUFSIZ], GET[BUFSIZ];
  char  header[BUFSIZ] = "";
  static char  text[BUFSIZ];
  int i;
  if(WSAStartup(MAKEWORD(2,2), &WSAData)) {
    printf("WSA 失败!\n");
    return false;
  }
  strcpy(myurl, url);
  for (pHost = myurl; *pHost != '/' && *pHost != '\0'; ++pHost);
  if ( (int)(pHost - myurl) == strlen(myurl) )
    strcpy(GET, "/");
  else
    strcpy(GET, pHost);
  *pHost = '\0';
  strcpy(host, myurl);
  sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  pURL = gethostbyname(host);
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = *((unsigned long*)pURL->h_addr);
  addr.sin_port = htons(80);
  strcat(header, "GET ");
  strcat(header, GET);
  strcat(header, " HTTP/1.1\r\n");
  strcat(header, "HOST: ");
  strcat(header, host);
  strcat(header, "\r\nConnection: Close\r\n\r\n");
  connect(sockfd,(SOCKADDR *)&addr,sizeof(addr));
  printf("正在发送请求...\n");
  send(sockfd, header, strlen(header), 0);
  bool ret = false;
  printf("正在处理请求...\n"); 
  while ( recv(sockfd, text, BUFSIZ, 0) > 0) 
    ret = true;
  char time[14] = {'\0'};
  int it = 0, remain = 0;
  while(text[it]){
    if(text[it]=='#'){
      remain = 14;
      it++;
      continue;
    }
    if(remain){
      time[14-remain] = text[it];
      remain--;
    }
    it++;
  }
  printf("成功获得时间:%s\n",time);
  printf("正在应用设置...\n"); 
  if(set_local_time(time))
    printf("设置时间成功!");
  else
    printf("设置时间失败,可能是没有权限");
  closesocket(sockfd);
  WSACleanup();
  return ret;
}

int main() {
  geturl("api.mmuaa.com/gettime");
  return 0;
}

在编译的过程中如果是DEV-cpp可能会提示编译错误,是因为代码通过socket连接服务器,获取数据,而编译器没有引入socket库导致的,在编译选项中添加编译参数-lws2_32即可

如果提示没有权限可能是被安全软件拦截,或者没有授予管理员权限,在属性中选中以管理员身份运行即可。

转载原创文章请注明,转载自: 斐斐のBlog » Windows下C语言API修改系统时间,附自动校准时间源码
评论已关闭