-
-
[原创]时间校对:UDP发NTP协议封包来获取时间(2,从NTP协议中解析时间戳并设置本机时间)
-
发表于:
2014-9-26 13:39
6311
-
[原创]时间校对:UDP发NTP协议封包来获取时间(2,从NTP协议中解析时间戳并设置本机时间)
之前说了发ntp查询包获取ntp回包.
http://bbs.pediy.com/showthread.php?p=1318896
这里说下解析出的时间戳的使用方法
NTPPack.TransmitTime
是NTP包离开NTP服务器时候的时间戳
首先注意.之前我将NTP时间戳定义为
typedef struct ntptime_t
{
UINT dwHighDateTime;
UINT dwLowDateTime;
}ntptime;
其中的high 高位其实是时间戳中的秒数
低位则是余出来的纳秒数
我们在发查询包之前 可以
ULONG RealTimeOut = GetTickCount();
获取下当时的count
然后再收到回包之后
RealTimeOut = (GetTickCount() - RealTimeOut) / 2;
即可获取延迟
我们可以将高位转换为time_t
time_t ntp_time = ntohl(NTPRecvPack.TransmitTime.dwHighDateTime) - 2208988800
然后将低位转换为系统的毫秒值
float Splitseconds;
Splitseconds = (float)ntohl(NTPRecvPack.TransmitTime.dwLowDateTime);
Splitseconds = (float)0.000000000200 * Splitseconds;
Splitseconds = (float)1000.0 * Splitseconds;
然后进行精度纠正:
if ((Splitseconds + RealTimeOut) > 1000)
{
Splitseconds += RealTimeOut % 1000;
ntp_time += RealTimeOut % 1000;
}else if((Splitseconds + RealTimeOut) = 1000)
{
ntp_time ++;
}else
{
Splitseconds += RealTimeOut;
}
然后我们将获取的Splitseconds与ntp_time转换为SYSTEMTIME
TimeStamp->wYear = lpLocalTime.tm_year + 1900;//时间戳是从1900年开始算
TimeStamp->wMonth = lpLocalTime.tm_mon + 1;//tm是从0开始 systemtime是从1开始
TimeStamp->wDay = lpLocalTime.tm_mday;
TimeStamp->wHour = lpLocalTime.tm_hour;
TimeStamp->wMinute = lpLocalTime.tm_min;
TimeStamp->wSecond = lpLocalTime.tm_sec;
TimeStamp->wMilliseconds = (USHORT)Splitseconds;
然后现在就可以调用
sprintf_s(Localtimestr,MAX_PATH,"%d-%d-%d %d:%d:%d",
TimeStamp.wYear,TimeStamp.wMonth,TimeStamp.wDay,
TimeStamp.wHour,TimeStamp.wMinute,TimeStamp.wSecond);
格式化为人常年的时间格式.
或者调用
SetLocalTime(&TimeStamp);
来设置本机时间了
http://blog.shajincheng.com/post/93.html
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!