获取网络时间
方法一:ping百度等服务器,获取时间
QNetworkAccessManager manager;
void CNetwork::verifyTime()
{
QNetworkRequest request(QUrl("http://open.baidu.com/special/time/"));
QNetworkReply *reply = manager.get(request);
connect(&manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(verifyLocalTime(QNetworkReply*)));
}
bool CNetwork::verifyLocalTime(QNetworkReply *reply)
{
#if 1
QRegExp rx("window.baidu_time\\((.+)\\)");
do{
QString str = QString::fromUtf8(reply->readLine());
qDebug() << __FUNCTION__ << reply->readLine();
int pos = str.indexOf(rx);
if(pos >= 0)
{
QDateTime time = QDateTime::fromMSecsSinceEpoch(rx.cap(1).toLongLong());
QString timeStr = DATETIME_TO_STRING(time);
if (time.isValid())
{
bool bRet = Util::setSystemTime(time);
g_log->logFunc2(LOG_INFO, "verify server time: %s, %d"
, timeStr.toUtf8().data(), bRet);
return bRet;
}
break;
}
}while(!reply->atEnd());
#endif
g_log->logFunc2(LOG_INFO, "verify server time failed");
return false;
}
方法二:从时间服务器NTP获取时间
void CNetwork::verifyTime()
{
QString ntpHost = "cn.ntp.org.cn";
//use ntp server get network time
QUdpSocket udp_sock;
udp_sock.connectToHost(ntpHost, 123);
//request server time
qint8 LI = 0;
qint8 VN = 3;
qint8 MODE = 3;
qint8 STRATUM = 0;
qint8 POLL = 4;
qint8 PREC = -6;
QDateTime epoch(QDate(1900, 1, 1));
qint32 second = quint32(epoch.secsTo(QDateTime::currentDateTime()));
qint32 temp = 0;
QByteArray time_req(48, 0);
time_req[0] = (LI <<6) | (VN <<3) | (MODE);
time_req[1] = STRATUM;
time_req[2] = POLL;
time_req[3] = PREC & 0xff;
time_req[5] = 1;
time_req[9] = 1;
time_req[40] = (temp=(second&0xff000000)>>24);
temp = 0;
time_req[41]=(temp=(second&0x00ff0000)>>16);
temp = 0;
time_req[42] = (temp=(second&0x0000ff00)>>8);
temp = 0;
time_req[43] = ((second&0x000000ff));
QDateTime cur_dt;
//block wait connect
if(udp_sock.waitForConnected(3000))
{
udp_sock.flush();
//request time
udp_sock.write(time_req);
QString s,tmp;
for(int i=0;i<48;i++)
{
tmp.sprintf("%.2X",(unsigned char)time_req[i]);
s.append(tmp);
tmp.sprintf(" ");
s.append(tmp);
}
//block wait reply
if(udp_sock.waitForReadyRead(5000))
{
QByteArray new_time;
QDateTime epoch(QDate(1900, 1, 1));
QDateTime unix_start(QDate(1970, 1, 1));
while(udp_sock.hasPendingDatagrams())
{
new_time.resize(udp_sock.pendingDatagramSize());
udp_sock.read(new_time.data(), new_time.size());
}
QString s,tmp;
for(int i=0;i<48;i++)
{
tmp.sprintf("%.2X",(unsigned char)new_time[i]);
s.append(tmp);
tmp.sprintf(" ");
s.append(tmp);
}
QByteArray TransmitTimeStamp ;
TransmitTimeStamp = new_time.right(8);
quint32 seconds=TransmitTimeStamp[0];
quint8 temp=0;
for(int j=1;j<=3;j++)
{
seconds=seconds<<8;
temp=TransmitTimeStamp[j];
seconds=seconds+temp;
}
cur_dt.setTime_t(seconds- epoch.secsTo(unix_start));
g_log->logFunc2(LOG_INFO, "get ntp time is ok: %s", DATETIME_TO_STRING(cur_dt).toUtf8().data());
Util::setSystemTime(cur_dt);
}
else
{
g_log->logFunc2(LOG_WARNING, "get ntp time is time out.");
}
udp_sock.disconnectFromHost();
udp_sock.close();
}
else
{
QHostInfo info = QHostInfo::fromName(ntpHost);
QString ip_addr = info.addresses().first().toString();
g_log->logFunc2(LOG_WARNING, "connect ntp server is error: %s", ip_addr.toUtf8().data());
}
}
//设置windows系统时间
bool Util::setSystemTime(const QDateTime &dateTime)
{
SYSTEMTIME st;
GetLocalTime(&st);
st.wYear = dateTime.date().year();
st.wMonth = dateTime.date().month();
st.wDay = dateTime.date().day();
st.wHour = dateTime.time().hour();
st.wMinute = dateTime.time().minute();
st.wSecond = dateTime.time().second();
// st.wDayOfWeek= 0;
st.wMilliseconds = dateTime.time().msec();
return SetLocalTime(&st);
}
常用时间服务器:
1.cn.pool.ntp.org
2.cn.pool.ntp.org
3.cn.pool.ntp.org
0.cn.pool.ntp.org
cn.pool.ntp.org
tw.pool.ntp.org
0.tw.pool.ntp.org
1.tw.pool.ntp.org
2.tw.pool.ntp.org
3.tw.pool.ntp.org