根据网络时间矫正系统时间

#define WIN32_LEAN_AND_MEAN
#include<Windows.h>
#include<winsock2.h>
#include <ws2tcpip.h>
#include<iostream>
#include<ctime>
#pragma comment (lib, "Ws2_32.lib")
#define socklen_t int
INT64 GetNTPTime()
{
	//初始化网络库
	WSADATA wsaData;
	::WSAStartup(MAKEWORD(2, 2), &wsaData);
	//下面是获取过程
	INT64 curTm = 0;
	struct hostent *host = NULL;
	int nErrno = 0;

	const char *server = "ntp.aliyun.com";
	const char *port = "123";
	ADDRINFOA hints, *res, *ap; /* address info structs */
	socklen_t addrlen = sizeof(struct sockaddr_storage);

	struct ntpPacket {
		UINT8 flags;
		UINT8 stratum;
		UINT8 poll;
		UINT8 precision;
		UINT32 root_delay;
		UINT32 root_dispersion;
		UINT8 referenceID[4];
		UINT32 ref_ts_sec;
		UINT32 ref_ts_frac;
		UINT32 origin_ts_sec;
		UINT32 origin_ts_frac;
		UINT32 recv_ts_sec;
		UINT32 recv_ts_frac;
		UINT32 trans_ts_sec;
		UINT32 trans_ts_frac;
	};
#define ENDIAN_SWAP32(data)  	((data >> 24) | /* right shift 3 bytes */ \
	((data & 0x00ff0000) >> 8) | /* right shift 1 byte */ \
	((data & 0x0000ff00) << 8) | /* left shift 1 byte */ \
	((data & 0x000000ff) << 24)) /* left shift 3 bytes */

	struct ntpPacket packet;
	UINT8 *ptr = (UINT8 *)(&packet); /* to read raw bytes */

	int server_sock; /* send through this socket */
	int error; /* error checking */
	unsigned int recv_secs;

	/* server is required, port is optional */
	memset(&packet, 0, sizeof(struct ntpPacket));
	packet.flags = 0xe3;

	memset(&hints, 0, sizeof(hints));
	hints.ai_socktype = SOCK_DGRAM;

	/* fill our address structs for ntp server */
	error = getaddrinfo(server, port, &hints, &res);
	/* loop through results */
	for (ap = res; ap != NULL; ap = ap->ai_next) {
		server_sock = socket(ap->ai_family, ap->ai_socktype, ap->ai_protocol);
		if (server_sock == -1)
			continue;
		break;
	}
	if (ap == NULL) {
		return curTm;
	}

	error = ::sendto(server_sock, (const char*)&packet, sizeof(struct ntpPacket), 0, ap->ai_addr, addrlen);
	if (error == -1) {
		return curTm;
	}
	error = recvfrom(server_sock, (char*)&packet, sizeof(struct ntpPacket), 0, ap->ai_addr, &addrlen);
	if (error == -1) {
		return curTm;
	}

	freeaddrinfo(res); /* all done */

	/* correct for right endianess */
	packet.recv_ts_sec = ENDIAN_SWAP32(packet.recv_ts_sec);

	/* print date with receive timestamp */
	recv_secs = packet.recv_ts_sec - 2208988800L; /* convert to unix time */
	curTm = recv_secs;

	return curTm;
}

void GetTime(int time, int& h, int& m, int& s)
{
	int day = 60 * 60 * 24;
	int days = time % day;
	h = days / 3600 ;//格林尼治标准时间与北京时间差8小时
	m = (days - h * 3600) / 60;
	s = days % 60;
	h += 8;
	printf("time:%02d:%02d:%02d\n", h, m, s);
}


int main()
{

	//获取网络时间
	INT64 time = GetNTPTime();
	int h, s, m;
	GetTime(time, h, s, m);


	//time_t t = std::time(NULL);
	struct tm p;
	localtime_s(&p,&time);
	int year = p.tm_year + 1900;
	int month = p.tm_mon + 1; //月份取值[0,11]
	int day = p.tm_mday;
	int hour = p.tm_hour;
	int minu = p.tm_min;
	int sec = p.tm_sec;
	char data[256] = {0};
	sprintf_s(data,256 - 1,"date %04d/%02d/%02d", year, month, day);
	printf("%s\n",data);
	system(data);
	
	char time2[256] = { 0 };
	sprintf_s(time2, 256 - 1, "time %02d:%02d:%02d", hour, minu, sec);
	
	printf("%s\n", time2);
	system(time2);

	system("pause");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值