本帖最后由 iamlimeng 于 2019-08-11 19:51 编辑
最近在校准家里的时钟,找了不少工具,获得的时间都不太精确,还是自己写吧。很久以前写过一个,由于算法问题,精度不够高,重写了算法,现在精度应该在0.1秒以内(前提是服务器时间精确)。
目前国内比较可靠,网络访问延时少的授时服务器有:阿里云授时服务器、国家授时中心服务器、NTP.ORG,当然苹果和微软的授时服务器也不错。
NTP(Network Time Protocol)网络时间协议基于UDP,用于网络时间同步的协议,使网络中的计算机时钟同步到UTC,再配合各个时区的偏移调整就能实现精准同步对时功能。NTP授时精度与NTP服务器与用户间的网络状况有关:广域网授时精度通常能达50ms级,但有时超过500ms;局域网授时不存在路由器路径延迟问题,因而授时精度理论上可以提到亚毫秒级;但是Windows内置NTP服务,在局域网内其最高授时精度也只能达10ms级。
IETF的RFC5905对NTP数据包的结构有详细说明。
万能的Perl就有效率比较高的解析模块Net::NTP,结合RFC5905文档的说明,将NTP服务器反馈的数据包解析后,只须对接收到的时间数据进行延时修正,就能获得准确的时间,这个精度对于一般用途足够了。
代码分享如下: - #!/usr/bin/perl
- =info
- Author: iamlimeng
- Date:2019-08
- =cut
- use strict;
- use warnings;
- use Net::NTP qw(get_ntp_response);
- $| = 1;
- my $interval = 0.999999;
- my $NTP_Server = 'ntp1.aliyun.com'; #阿里云授时服务器,可靠性高
- #my $NTP_Server = 'ntp.aliyun.com'; #阿里云授时服务器,可靠性高
- #my $NTP_Server = 'ntp.ntsc.ac.cn'; #国家授时中心,可靠性高
- #my $NTP_Server = 'cn.ntp.org.cn';
- print "NTP Server: $NTP_Server\n\n";;
- my %response = eval { get_ntp_response($NTP_Server) };
- if (%response) {
- my $time = $response{'Transmit Timestamp'} + $response{'Delay'}/2;
- my ($now,$wait) = split(/\./,$time);
- select(undef, undef, undef, 1-$wait/100000);
- while(1) {
- $now++;
- print "\r",time_from_utc($now);
- select(undef, undef, undef, $interval);
- }
- }
- else { print "Connect NTP Server Faild!"; }
- <STDIN>;
- exit;
- sub time_from_utc {
- my $utc = shift;
- my ($sec,$min,$hour,$day,$mon,$year,$weekday,$yeardate,$savinglightday) = (localtime($utc));
- return (sprintf("%04d.%02d.%02d %02d:%02d:%02d",$year+1900,$mon+1,$day,$hour,$min,$sec));
- }
复制代码
|