我从其他用户那里获得了代码 link
我连接到:pool.ntp.org
但我不能及时发现任何差异。 (我需要与ntp服务器完美同步 - 然后我会很高兴)
我的代码:
time_t t = response.tx.to_time_t();
char *s = ctime(&t);
WSACleanup();
h_qtimeonStatusBar->setDateTime(QDateTime::fromTime_t(response.tx.to_time_t()));
但首先我有这段代码:
getNTPTime(); //function above
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(updateTime())); // update time = current time from 'getNTPTime()' + 1 s
timer->start(0);
timer->setInterval(1000);
我的差异是以毫秒为单位(最大1000),但它确实可见。 我的时钟比ntp服务器慢慢点亮(这是可靠的信息)
如何摆脱这种差异?
我试着用它:
//func run after program start
{
getNTPTime();
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(updateTime()));
timer->start(0);
timer->setInterval(1000);
}
bool plemionabot1::getNTPTime(){
using namespace std::chrono;
WSADATA wsaData;
DWORD ret = WSAStartup(MAKEWORD(2, 0), &wsaData);
char *host = "pool.ntp.org"; /* Don't distribute stuff pointing here, it's not polite. */
//char *host = "time.nist.gov"; /* This one's probably ok, but can get grumpy about request rates during debugging. */
NTPMessage msg;
/* Important, if you don't set the version/mode, the server will ignore you. */
msg.clear();
msg.version = 3;
msg.mode = 3 /* client */;
NTPMessage response;
response.clear();
int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
sockaddr_in srv_addr;
memset(&srv_addr, 0, sizeof(srv_addr));
msg.dns_lookup(host, &srv_addr); /* Helper function defined below. */
msg.sendto(sock, &srv_addr);
auto t0 = high_resolution_clock::now();
response.recv(sock);
time_t t = response.tx.to_time_t();
char *s = ctime(&t);
WSACleanup();
//QDateTime * tmp = new QDateTime;
//tmp->setMSecsSinceEpoch(response.tx.seconds); // time is too much
//h_qtimeonStatusBar->setDateTime(tmp->currentDateTime());
h_qtimeonStatusBar->setDateTime(QDateTime::fromTime_t(response.tx.to_time_t())); // tą opcją wychodzi za mało
auto t1 = high_resolution_clock::now();
h_qtimeonStatusBar->setTime(h_qtimeonStatusBar->time().addMSecs(duration_cast<milliseconds>(t1-t0).count())); // time not enough
return true;
}
答案 0 :(得分:2)
精度和定时器分辨率
定时器永远不会超过指定的超时值超时,并且不能保证它们以指定的确切值超时。在许多情况下,它们可能会延迟一段时间,这段时间取决于系统计时器的准确性。
您无法依靠QTimer
为您保留准确的时间。
相反,您需要做的是计算自上次查询NTP服务器以来的已用时间。经过的时间取决于您的系统时钟,它可能也会漂移,但这不是同一个问题。记录查询NTP服务器后经过的时间,并将其添加到查询NTP服务器时的系统时钟时间,以更好地估计当前的NTP时间。
更好的方法是设置ntpd,以便系统时钟自动调整到NTP时间。那么您的应用程序不必担心这一点,您只需显示系统时间即可。