程序员学习时间的由来

我们在写代码时,也经常会调用「时间 API」,你有思考过这背后的原理吗?

和时间相关的问题,还有很多:

  • 计算机的时间有时候「走不准」?
  • 计算机是怎么「自动校准」时间的?
  • UTC 时间,到底是什么?
  • 「北京时间」,真的来自北京吗?

时间为何会“不准”

为什么老钟表或者一台长时间不使用的电脑,它会走得「不准」了。此时,我们就「人工」调准它。但为什么它们的时间会越走越不准呢?

钟表和计算机内部都有一个叫做「晶体振荡器」的东西,给它加上电压,它就会以固定的频率振动。但这个振动频率的「稳定性」,取决于它的制造工艺,以及外界环境的影响。

出于成本的考虑,钟表的制作工艺没那么高,所以它更容易有误差。而电脑制造工艺虽然比较高,但它内部的晶体振荡器也会受到「温度」变化带来的影响,在工作过程中,也会有产生误差。

虽然它们的误差很小,但日积月累下来,误差就越来越明显。因此,我们现在使用的计算机,都有「自动校准」时间的功能。但是如何校准呢?

时间的校准

计算机联网会自动与「网络时间」保持同步,「网络时间」哪儿来的?每台电脑肯定配置了一个「时间服务器」,之后这台电脑会与服务器定时同步,自动校准。

「时间服务器」它应该也是一台计算机,它的时间就一定是准的吗?网络时间究竟是怎么「同步」到我们的电脑上的?网络传输数据也是有「延迟」的,同步服务器时间,不还是存在误差吗?

想要搞懂这些问题,就要从时间是怎么来的入手。

时间的「源头」

我们将目光聚焦在计算机这个范畴内。公转一周就被定义为 一「年」。

而一天平均划分为 24 等份,这就是「时」。把 1 小时划分 60「分钟」,1 分钟划分为 60「秒」。时间的基本单位「秒」就被定义出来了。所以,秒与天的关系就是这样的:1 秒 = 1 / 24 * 60 * 60 = 1 / 86400 天

由于「天」是通过在地球上,观测太阳照射这个同一位置的时间测出来的,公转轨道是椭圆,意味着每天照射同一位置的时间也有误差了。聪明的人们通过把一年内所有天的时长加起来,然后求「平均」,得到相对固定的「天」,然后再计算得出「相对平均」的秒,这样就减小了误差。

从摆钟到机械钟,再到现代广泛使用的石英钟,钟表的制作工艺越来越高,时间精度也越来越高,现代石英钟每天的计时误差只有「千分之一秒」。

所以,在 1927 年,人们以基于「天文现象」+「钟表计时」,确立了第一套时间标准:世界时(Universal Time,简称 UT)

我们经常听到的「格林尼治标准时间」(Greenwich Mean Time,简称 GMT),就是指的世界时,因为世界时是在这个英国伦敦格林尼治天文台观测计算出来的!

但是,随着科技的发展,人类对太阳的观测越来越精准,有意思的事情发生了。

然而地球每天的自转速度也「不是匀速」的,地球的自转受到潮汐、地壳运动、冰川融化、地震等自然现象的影响,越来越慢!这会导致之前规定的,每年平均下来一天的时间,也是不一样长的,按照 1 秒 = 1 / 86400 天的定义,每一年的「秒」,也是不一样长的。

虽然,对于人们的基本生活影响其实并不大。但随着人类活动的发展,人们对于高精度的时间场景开始变得越来越多。例如,体育赛事中百分之一秒的差距就能决定胜负,炮弹的发射要精确在千分之一秒内发生,雷达技术甚至需要精确到百万分之一秒...

既然宏观天文现象无法解决这个问题,人们开始把目光投向了「微观世界」。

1秒的长度

人们期望每一秒都是固定「等长」的,即有一个「完全稳定」的周期。

人们注意转移到了原子世界,每个原子都有一个原子核,核外分层排布着高速运转的电子,当原子受电磁辐射时,它的轨道电子可以从一个位置「跳」到另一个位置,物理学上称此为「跃迁」。

人们发现,原子内的电子发生跃迁时,原子会吸收或放出一定能量的「电磁波」,这类电磁波就是一种「周期运动」,也叫做原子内部的「振荡」。

基于这个原理,科学家们发现了 铯原子,它内部的振荡周期比其它原子都要更短、更稳定,而且,这个过程基本不受环境因素的干扰。

之后,科学家们就以之前定义的「秒」为基础,去测量一秒内这个铯原子内部电子周期运动的「次数」,测量出来的结果为 9192631770 次(91 亿+次)。

基于此,科学家们决定「抛弃」原来基于天文测量的秒,重新定义「秒」的时长,就是这个高度稳定的运动周期。

因此,在 1967 年,国际度量衡大会决定采用,以铯原子跃迁 9192631770 个周期,所持续的时间长度定义为 1 秒!

而基于这个铯原子振荡制造出来的时钟,我们就把它称之为「原子钟」。最新原子钟「精准计时」甚至可以达到 1 亿年不差 1 秒!!

人们基于原子钟又确立了一套新的时间标准,叫做「国际原子时」(International Atomic Time,简称 TAI)。规定,从 1958-01-01 00:00:00 起,用原子时开始计时,每一秒,都是非常精确稳定的一秒(固定等长)。

可否让国际原子时直接取代掉前面说的——以天文现象计时的「世界时」呢?答案是不能。

世界标准时间

因此,现在存在两套时间标准:

假设我们以国际原子时为日常时间标准,而原子时非常稳定,但世界时随着地球自转变慢:原子时走得快,世界时走得慢,时间越久,两者差距越来越大,几千年后,太阳正午的时刻,原子时可能已经走到了晚上。科技发展需要高度稳定的计时标准,人类生活需要天文测算指导,这两者的矛盾应该如何解决呢?

既然两套时间标准都重要,建立一套「新的时间标准」,以「原子时为基准」,持续观测「世界时」与这个新时钟的差距,相差过大的时候「人为」地调整一下这个时钟(加一秒或减一秒)。相当于让快的以「原子时为基准」的时钟稍微「等」一下走得慢的世界时:

 这加的一秒称为闰秒。

由于这个时钟是基于原子时 + 世界时「协调」得出的,所以科学家们把它定义为协调世界时(Coordinated Universal Time,简称 UTC)。

 

依此,有技术能力的国家都计算协调世界时。同时,每个国家会在每个月,统一上报自己计算的协调世界时到一个权威机构,进行加权计算,算出「最终」的协调世界时, 进一步降低原子钟的测量误差,再把这个最终的时间下发到各个国家,让各个国家进行「对表」校准,保证全世界的时间误差在 100 纳秒以内,也就是沿用至今的「标 准 时 间」。

中国的是位于陕西省西安市临潼区的「中国科学院国家授时中心」,陕西省的地理位置处于中国的中部,从这个位置向各地广播时间时,对全国每个地区距离都是相对平均的。我国会在协调世界时的基础上,再加 8 个小时(东八区),最终得出来的时间,就是「北京时间」。北京时间并不是在北京产生的,而是在陕西省,并与参与世界时间的制定和校准。

那最后我们就应该揭晓标准时间到底是如何同步到我们的电脑、手机、电子设备上的呢,也就是「授时」。

时间同步

位于陕西省的中国科学院国家授时中心,产生北京时间后,会通过无线电波、网络、电话,把这个时间广播出去,这个过程,就叫做「授时」。

由于无线电波的传播速度更快、传播误差小,授时中心会通过这种方式,把时间发送给全国各地的「时间服务器」。

时间服务器再通过其它方式(例如网络)广播同步到下一层的终端用户(计算机)使用。

数据在网络传输过程中,也是需要时间的,这个时间也会影响到时间的准确性。那计算机如何和它保持同步呢?解决办法就是当计算机在做时间校准时,也需要把网络延迟计算进去,最后「修正」这个同步过来的时间,降低误差。

部署应用程序的服务器上,都会启动一个叫 NTP(Network Time Protocol) 的「自动校准」时间服务 ,它可以保证每台机器的时间与时间服务器保持同步。

首先,NTP 如何同步时间?

简单来讲,它是通过在网络报文上打「时间戳」的方式,然后配合计算网络传输延迟,从而修正本机的时间:

假设网络来回路径是对称的,并且时延相同。根据图示可以计算出网络「传输延迟」,以及客户端与服务端的「时间差」:

  • 网络传输延时 = (t4 - t1) - (t3 - t2)
  • 时间差 = t2 - t1 - 网络延时 / 2 = ((t2 - t1) + (t3 - t4)) / 2

如此方式计算的同步时间误差在广域网下是 10ms - 500ms,在局域网下通常可以小于 1ms。

其次,同步时间时,对正在运行的程序有没有影响?

例如,我们很多时候写的程序代码是这样的:

t1 = Date.now()
/** 时间发生校准 */
t2 = Date.now()

/** t2比t1小怎么办? */
elapsed = t2 - t1

这里就牵涉出 2 个概念:

  • 墙上时钟:协调世界时 UTC,校准时间后,可能发生回拨。
  • 单调时钟:计算机自启动后经历的纳秒数,不会回拨

代码中的「时间 API」,通常获取的时间是墙上时钟,所以,如果时间发生校准,就可能会发生「时光倒流」的情况。如何解决呢?

NTP 在校准时间时,提供了 2 种方式:

  1. ntpdate:一切以服务端时间为准,「强制修改」本机时间
  2. ntpd:采用「润物细无声」的方式修改本机时间,把时间差均摊到每次小的调整上

也就是说,ntpd 当接收到需要「回拨」的时间时,会让本机时间走得「慢」一点,小步调整,逐渐与服务端的时钟「对齐」,这样一来,本机时间依旧是递增的,避免发生「倒流」。

总结

当我们在配置 ntp 服务时,需要格外注意这种情况。

另外,在编写程序时,也要注意调用的时间 API 获取的是哪个时间,避免业务逻辑发生异常。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

薛定谔的猫96

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值