这个方案非常棒,至此总算解决了秒不固定长的问题。
那有了这个国际原子时电脑日期时间不能同步,可否让它直接替代掉上面说的——以天文现象计时的「世界时」呢?
答案是否定的,这个问题远比想像的复杂得多,这是为什么呢?
世界标准时间是如何来的?
现在,科学家制订出了两套时间标准:
世界时:基于天文现象 + 钟表计时,永远与地球自转时间相匹配
国际原子时:基于原子钟计时,每一秒的周期完全等长且固定
假设我们以国际原子时为时间标准,那会发生哪些现象呢?
因为原子时十分稳定,但世界时随着地球自转变慢,会越来越慢,就会发生此类现象:
晚上 8 点是太阳高照的时刻,你能想像这些情况吗?
这太颠覆我们的生活认知了...
基于天文测算的世界时,已经指导我们人类生活了上千年,人类已经习惯了这些时间标准,直接被原子时代替,肯定是不能接受的。
但我们又须要原子时这些高度稳定的计时标准,来发展科学研究,两者发生矛盾,这如何办?
科学家们又开始思索,终于想到一个相互兼容的解决方案。
既然两套时间标准都很重要,那三者都保留,不会相互替代。
我们可以再完善一套「新的时间标准」,这套时间以「原子时为基准」,开始计时,走的每一秒都是稳定、精确的。
同时,为了兼具基于天文检测的世界时,人类会「持续观测」世界时与这个新时钟的差别。
如果发觉二者相差过大时,我们就「人为」地调整一下这个时钟(加一秒或减1秒),让二者相差不超过 0.9 秒。
例如,这个时钟本身比世界时走得快,经过一段时间后,如果发觉二者相差越来越大,那就给这个时钟「加一秒」,让这个时钟在 23:59:59 的下一秒变为 23:59:60 秒,让它与世界时差别控制在 0.9 秒以内,这个操作过程,相当于让快的时钟稍为「等」一下走得慢的世界时。
而加的这1秒,科学家把它定义为「闰秒」。
是不是挺有意思?听说过闰月,没想到还有闰秒!
当然,当地球自转速度变快时,这里也有可能是减1秒,即从 23:59:58 直接跳到 00:00:00。但此类情况比较少,大部分情况下,地球自转速度是越来越慢的。
这么做的用处在于,这个时钟的每一秒的计时仍然是精确的,而且还兼具了日常生活使用的世界时,一举两得!
由于这个时钟是基于原子时 + 世界时「协调」得出的,所以科学家们把它定义为协调世界时(Coordinated Universal Time,简称 UTC)。
看到了么?我们在开发时常常见到的 UTC,原来是这样来的!
有了这个研究成果,有技术能力的国家都纷纷制造自己的原子钟,然后估算协调世界时。
同时,为了进一步增加原子钟的测量误差,每个国家会在每个月,统一上报自己估算的世界协调时到一个权威机构,然后这个权威机构会依照各国实验室的精度,进行加权估算,算出「最终」的协调世界时。
之后,再把这个最终的时间下发到各个国家,让各个国家进行「对表」校准,保证全世界的时间偏差在100 纳秒以内。
至此,科学家们构建的这套时间标准,就是我们现今承袭至今的「标 准 时 间」!
值得一提的是,配合估算世界协调时的国家,也有中国,这个实验室就是「中国科学院国家授时中心」,它坐落中国的陕西省渭南市蒲城县,持续维护中国的标准时间。
为什么国家授时中心会筹建在陕西省?因为陕西省的地理位置处于中国的中部,从这个位置向各地广播时间时,对全省每位地区距离都是相对平均的。
之后,中国会在自己算出的世界协调时的基础上,再加 8 个小时(中国在东八区),最终得下来的时间,就是「北 京 时 间」!
没错,就是我们常常在新闻播报上看到的,北京时间。
是不是挺有意思?北京时间并不是在上海形成的,而是在陕西省,并与参与世界时间的制订和校正。
至此,全新的世界标准时间确立了,这套时间标准于 1972 年即将确定,一致承袭至今。
有了标准时间,那么接下来的问题就是,这个标准时间究竟是怎样同步到我们的笔记本、手机、电子设备上的呢?
这就是下边要讲的「授时」。
计算机怎么同步时间?
到现今我们晓得,世界标准时间和北京时间是如何来的,但北京时间的形成是在陕西省,难道校正一次时间须要挪到这儿吗?
很显然是不需要的。
位于陕西省的中国科学院国家授时中心,产生北京时间后,会通过一系列方法,把这个时间广播出去,这个过程,就叫做「授时」。
具体如何做呢?
国家授时中心提供好多授时形式,例如无线电波、网络、电话,都可以把时间广播出去。
通常来说,无线电波的传播速率更快、传播误差小,所以授时中心会通过这些方法,把时间发送给全国各地的「时间服务器」。
时间服务器有了确切的时间后,再通过其它方法(例如网路)广播到下一层的终端用户使用。
经过那么一番研究,到这儿我们就可以解释文章开头的问题了。
一个时间服务器,原来是通过国家授时中心同步时间,然后再给其它终端提供时间同步服务的。
那我们的计算机怎样和它保持同步呢?
你可能会想,最简单的方法就是,客户端向服务端「请求获取」标准时间,服务端响应时间数据,客户端更改自己的「本机时间」即可。
但事情没你想的那么简单。
因为数据在网路传输过程中,也是须要时间的,这个时间也会影响到时间的准确性。
这如何办呢?
于是人们想了一种方案,当计算机在做时间校正时,也须要把网路延后估算进去,最后「修正」这个同步过来的时间,降低偏差。
现在,已经有个软件早已把这一切都做好了,如果你了解一些运维相关的工作,就会晓得,我们布署应用程序的服务器上,都会启动一个「自动校正」时间的服务,这个服务就是 NTP(Network Time Protocol),它可以保证每台机器的时间与时间服务器保持同步。
那 NTP 是如何同步服务器时间的呢?
这里就涉及到 2 个重点:
NTP 如何同步时间?
同步时间时,对正在运行的程序有没有影响?
先来看第一个问题:NTP 如何同步时间?
简单来讲,它是通过在网路报文上打「时间戳」的形式,然后配合估算网路延后,从而修正本机的时间。
根据图示可以估算出网路「传输延后」,以及客户端与服务端的「时间差」:
这个估算过程假定网路来回路径是对称的,并且信噪比相同。
这样一来,客户端就可以「校准」自己的本机时间了,与服务端保持同步,这个时间偏差在广域网下是 10ms - 500ms,在局域网下一般可以大于 1ms。
再来看第二个问题:同步时间时,对正在运行的程序有没有影响?
例如,我们好多时侯写的程序代码是这样的:
t1 = time.now()
// 时间发生校准
t2 = time.now()
// t2比t1小怎么办?
elapsed = t2 - t1
t2 的时间真的会比 t1 小吗?
这里就牵连出 2 个概念:墙上时钟、单调时钟,它们之间有哪些区别呢?
一般我们写的代码,像前面程序调用的「时间 API」,通常获取的时间是墙壁时钟,所以,如果时间发生校正,就可能会发生「时光倒流」的情况。
这必然对程序形成很大的影响,怎么解决这个问题呢?
幸运的是,NTP 在校正时间时,提供了 2 种形式:
ntpdate:一切以服务端时间为准,「强制更改」本机时间
ntpd:采用「润物细无声」的形式更改本机时间,把时间差分摊到每次小的调整上
也就是说,ntpd 当接收到须要「回拨」的时间时,会让本机时间走得「慢」一点,小步调整,逐渐与服务端的时钟「对齐」,这样一来,本机时间仍然是递增的,避免发生「倒流」。
当我们在配置 ntp 服务时,需要愈发注意这些情况。另外,在编撰程序时,也要注意调用的时间 API 获取的是那个时间,避免业务逻辑发生异常。
至此,我们从看似简单的时间问题,一步步深挖到时间的定义,再到时间是怎样同步到计算机和终端设备的,怎么样,有没有解答了你心里的好多疑虑?
总结
好了,总结一下。
这篇文章我们讲了特别多的概念,这里我们再重新梳理一遍。
1、人类的初期生活,依靠观测「天文现象」来检测时间,基于地球自转规律,定义了一套时间标准:「世界时」。
2、后来人们发觉,由于地球公转轨道是一个椭圆,并且地球自转还遭到月球内部的影响,自转速率越来越慢,人们发觉世界时测算出的时间「不准」。
3、科学家们开始从「微观世界」寻找更稳定的周期运动,最终确定以「铯原子」的震动频度为基准,制造出了「原子钟」,确立了「世界原子时」,并重新定义了「秒」长度,时长高度精确。
4、但因为人类社会活动已高度依赖「世界时」,所以科学家们基于「原子时」和「世界时」,最终确立出新的时间标准:「世界协调时」,把它定义成了全球的时间标准,至此,世界标准时间诞生。
5、中国基于「世界协调时」再加上 8 小时时区之差,确立了「北京时间」,并广播给整个中国大地使用。
6、「国家授时中心」把北京时间广播给全省的「时间服务器」,我们生活中使用的时间,例如计算机,就是通过时间服务器手动同步校正的。
7、计算机通过 NTP 完成和时间服务器的「自动校正」,我们的应用程序基于此,才得以获取到确切的时间。
8、NTP 服务应当采用润物细无声的形式同步时间电脑日期时间不能同步,避免时间发生「倒流」。
往期干货笔记整理