很多情况导致电脑开机后总是从00:00开始,如主板CMOS电池供电不足。时间不对有时会导致网络浏览提示日期没有更新而不能正常访问。虽然Windows系统也有同步到internet时间的操作界面,需要多次点击。但如果是旧电脑,每次开机都要去更新这个时间,非常繁琐。所以,可以写一个自动将本地时间同步到网络时间的小程序。
1 C语言如何设置Windows平台的本地时间
1.1 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;1.2 设置本地时间的API
windows.h提供的函数SetLocalTime()可以设置本地时间。
BOOL WINAPI SetLocalTime( _In_ const SYSTEMTIME *lpSystemTime );其参数就是上述的结构体指针。
_In_在visual C++中属于SAL批注,是为了编译系统在分析代码时发现缺陷用的。表示是一个输入参数。类似的还有_Out_。
2 获取某些网站页面返回的时间字符串
如以下站点
http://quan.suning.com/getSysTime.do
页面显示:
{"sysTime2":"2022-08-10 08:40:08","sysTime1":"20220810084008"}
通过socket套接字编程即可提取到该页面返回的字符串,如:
19,36,200-0,M], cache20.cn3603[43,0]
X-Cache: MISS TCP_MISS dirn:-2:-2
X-Swift-SaveTime: Wed, 10 Aug 2022 00:50:57 GMT
X-Swift-CacheTime: 0
Timing-Allow-Origin: *
EagleId: 708422a816600926577736154e
{"sysTime2":"2022-08-10 08:50:57","sysTime1":"20220810085057"}-cache,no-store,ma
x-age=0,s-maxage=0
Access-Control-Allow-Credentials: true
es-suning-dnsstr: quan.suning.com:tradema:default
Ali-Swift-Global-Savetime: 1660092657
Via: cache46.l2cn3036[8,10,200-0,M], cache79.l2cn3036[12,0], cache3.cn3603[…
3 提取需要的字符串
4 调用SetLocalTime()设置本地时间
code demo:
#include #include #include #include #pragma comment(lib, "ws2_32.lib")/* * 国家授时中心 http://www.ntsc.ac.cn/ * 获取网络时间的网站API * 苏宁 http://quan.suning.com/getSysTime.do * 淘宝 http://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp * QQ http://cgi.im.qq.com/cgi-bin/cgi_svrtime**/char* getTimeTxt(char *url);int set_local_time(const char *timeStr);int main() { char * time = getTimeTxt("quan.suning.com/getSysTime.do"); if(time==NULL) { printf("返回的是乱字符串!
"); printf("3秒后自动关闭窗口……"); Sleep(3000); exit(1); } printf("正在应用设置...
"); //strcpy(time,"20220807174237"); //printf("%s
",time); if(set_local_time(time)==0) printf("设置时间成功!
"); else printf("设置时间失败,可能是没有权限"); printf("3秒后自动关闭窗口……"); Sleep(3000); //getTimeTxt("api.mmuaa.com/gettime"); //getchar(); return 0;}char* getTimeTxt(char *url) { WSADATA WSAData= {0}; if(WSAStartup(MAKEWORD(2,2), &WSAData)) { // WSAStartup printf("WSA 失败!
"); return false; } SOCKET sockfd; sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); // socket char myurl[BUFSIZ]; strcpy(myurl, url); char *pHost = 0; char GET[BUFSIZ]; for (pHost = myurl; *pHost != '/' && *pHost != '\0'; ++pHost); // ↓ if ( (int)(pHost - myurl) == strlen(myurl) ) strcpy(GET, "/"); else strcpy(GET, pHost); *pHost = '\0'; struct hostent *pURL; pURL = gethostbyname(myurl); struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = *((unsigned long*)pURL->h_addr); // ↑ addr.sin_port = htons(80); connect(sockfd,(SOCKADDR *)&addr,sizeof(addr)); // connecting printf("正在给网络API(%s)发送请求...
",url); char header[BUFSIZ] = ""; strcat(header, "GET "); strcat(header, GET); strcat(header, " HTTP/1.1\r
"); strcat(header, "HOST: "); strcat(header, myurl); strcat(header, "\r
Connection: Close\r
\r
"); send(sockfd, header, strlen(header), 0); // sending printf("正在处理请求...
"); static char text[BUFSIZ*2]; while ( recv(sockfd, text, BUFSIZ, 0) > 0); // receiving closesocket(sockfd); WSACleanup(); text[BUFSIZ*2-1] = '\0'; if(strlen(text) == 0) printf("text is empty!
"); else printf("
网络API(%s)返回字符串:
%s
",url,text); char* subStr = "sysTime1"; // 文本处理 char* str = strstr(text,subStr); if(str == NULL) return NULL; str = str + strlen(subStr) + 3; // "sysTime1":"20220807203344 //printf("abc 123 %s
",str); char *time = (char*)malloc(sizeof(char)*15); strncpy(time,str,14); time[14] = '\0'; printf("
成功获得时间:%s
",time); return time;}/* * @function : 设置Windows本地时间 * @in : timeStr - 14字节时间字符串(such as 20150415093000) * @return : 0 - success * -1 - failure **/int set_local_time(const char *timeStr) { 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, timeStr + index, 4); index += 4; strncpy(month, timeStr + index, 2); index += 2; strncpy(day, timeStr + index, 2); index += 2; strncpy(hour, timeStr + index, 2); index += 2; strncpy(minute, timeStr + index, 2); index += 2; strncpy(second, timeStr + 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; } 当然,以上小程序要手动运行才可以同步网络时间,要自动同步的话,可以通过”计划任务“自动运行。
以上代码没有考虑网络延迟的问题。在从服务器获取时间数据时,由于网络本身的不稳定性,一般会有时间上的延迟(几秒以内),这样一来,从服务器接收到的数据总早于真实时间。解决的办法是设定一个计时器,计算出本机从开始网络连接到接收完数据所耗费的时间dwDelay,然后加到 dwTime 上进行补偿。这样一来误差就可以控制在1秒以内。
以下网站返回的时间是豪秒数:
http://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp
页面显示:
{"api":"mtop.common.getTimestamp","v":"*","ret":["SUCCESS::接口调用成功"],"data":{"t":"1660091956996"}}
表示从1900.1.1至现在流逝的时间:
#include #include int main (){ time_t timer; // typedef long time_t struct tm y1900 = {0}; double seconds; // 定义1900.1.1 y1900.tm_hour = 0; y1900.tm_min = 0; y1900.tm_sec = 0; y1900.tm_year = 0; y1900.tm_mon = 0; y1900.tm_mday = 1; time(&timer); /* get current time; same as: timer = time(NULL) */ seconds = difftime(timer,mktime(&y1900)); printf ("lapsed %.f seconds since January 1, y1900 to now in the current timezone", seconds); getchar(); return 0;}/*output:lapsed 1660093185 seconds since January 1, y1900 to now in the current timezone*/ localtime()可转换时间格式:
#include #include // struct tm * localtime (const time_t * timer);#if 0struct tm { int tm_sec; /* seconds after the minute - [0,59] */ int tm_min; /* minutes after the hour - [0,59] */ int tm_hour; /* hours since midnight - [0,23] */ int tm_mday; /* day of the month - [1,31] */ int tm_mon; /* months since January - [0,11] */ int tm_year; /* years since 1900 */ int tm_wday; /* days since Sunday - [0,6] */ int tm_yday; /* days since January 1 - [0,365] */ int tm_isdst; /* daylight savings time flag */};#endifint main (){ time_t rawtime; struct tm * timeinfo; time (&rawtime); timeinfo = localtime (&rawtime); printf ("Current local time and date: %s", asctime(timeinfo)); getchar(); return 0;}/*output:Current local time and date: Wed Aug 10 09:06:33 2022*/ ref
https://www.mmuaa.com/post/3281abd440aeb073.html
https://www.likecs.com/show-306240829.html
-End-
| 留言与评论(共有 0 条评论) “” |