时间系列之各种时间的意义

那些令人迷惑的时间

Posted by 夏敏的博客 on February 10, 2018

本章为时间系列的第二章,带来我们各种常见的时间名词的意义。

GMT-格林尼治标准时间

GMT(Greenwich Mean Time)是格林尼治标准时间。格林尼治是英国伦敦南郊原皇家格林尼治天文台所在地,地球本初子午线的标界处,世界计算时间和经度的起点。本初子午线就是零度经线。

所谓的时区也就是从本初子午线那开始划分的,整个地球分为二十四时区,中国的时区为东八区,因此叫GMT+8,我们手机里选择时区的时候就可以看到中国标准时间为GMT+08:00

下图就是本初子午线。

在 1880 年代的时间标准以 GMT时间为主的,但是 GMT 时间是以太阳通过格林威治那一刻作为标准的, 然而我们都知道,地球自转和公转并非圆形,另外地球自转速度好像在逐年递减 所所以GMT时间就有点不准确了。

UTC-世界协调时间

UTC(Coordinated Universal Time)世界协调时间(又称世界标准时间、世界统一时间),是经过平均太阳时(以格林威治时间GMT为准)、地轴运动修正后的新时标以及以「秒」为单位的国际原子时所综合精算而成的时间,计算过程相当严谨精密,因此若以「世界标准时间」的角度来说,UTC比GMT来得更加精准。其误差值必须保持在0.9秒以内,若大于0.9秒则由位于巴黎的国际地球自转事务中央局发布闰秒,使UTC与地球自转周期一致。所以基本上UTC的本质强调的是比GMT更为精确的世界时间标准。

网络标准时间就是根据UTC来的。我们平时提到的UTC与GMT实际上为同一个时间,都是标准时间,只不过一个是天文上的概念,一个基于原子钟。

DST-夏日节约时间

DST是Daylight Saving Time的缩写,称为阳光节约时,在我国称为夏时制,或者夏令时。

关于夏令时的文章见上篇时间知识介绍开篇之夏令时(夏时制)

UNIX时间戳

1970年的1月1日(GMT或UTC时间),这一天是计算机的创世纪之日,用小说里面的话说:这天是一个新的纪元的开始。Unix时间戳就是从那天起到现在的秒数。 到我写这篇文章的时间,时间已经过去了1518244692秒。另外,Unix时间戳不仅被使用在Unix系统、类Unix系统中,也在许多其他操作系统中被广泛采用。

我们在Java中可以使用System.currentTimeMillis(),将返回自1970年1月1日至现在的时间,以毫秒为单位返回一个long类型。事实上System.currentTimeMillis()方法的时间粒度是大于1毫秒的。如果你反复执行这个方法,你会发现短时间内得到的结果是相同的,随后又突然在某一次结果增加了几十毫秒(也可能更多)。

大家也应该听说过,很多语言或者计算机系统里是用32位整型来表示时间戳的,而32为能表示的最大值就是2147483647,那么按这个计算的话,2038年1月19号中午11点14分左右的时候,所有32位应用程序得到的Unix Timestamp结果都将溢出,若没有对这个进行处理,那么程序将会产生异常。

在命令行里可以使用:perl -e “print time”来获取时间戳

Java中精准时间

从java5之后,System类提供了一个新方法 nanoTime 这个方法返回纳秒计数器,1纳秒=0.00000 0001秒,不能用它来获得决定时间,但是可以获得时间差。System.nanoTime()是基于CPU时钟周期来确定的,其不能保证精确度,应用场景可以为,测试代码的执行时间。

long startTime = System.nanoTime();
// ... the code being measured ...
long estimatedTime = System.nanoTime() - startTime;

需要记得的是,System.nanoTime()是基于CPU时钟周期来确定的,并且单位为纳秒级别,而在多核处理器上,每个核启动的时间是不一致的,会有略微时间差。

RTC硬件时钟

计算机以及其他电子设备里面的时间,也需要自己计算的,甚至很多设备是不需要联网的,那他们的时间是哪来的呢,这个时间就来自于RTC时钟。

还记得大学去淘宝买最小系统板,上面都有个放纽扣电池的地方,那就是给RTC时钟供电的,RTC时钟就相当于我们系统里的原子钟,其通过震荡原理,经过分频,最后得到秒级的增加。每种芯片都有自己的独特的震荡周期,然而因为芯片的震荡周期在不同的芯片之间多多少少都会有点差异性,甚至同一批芯片也可能会或多或少有些许的差异 (就连温度也可能造成这样的误差), 因此RTC的时间并不能保证非常的准确,长期运行下来有可能会有几秒的差别。如果长期积累下来,时间不准问题会越来越严重。

如果在设备本身已经无法提供准确时间的情况下,我们就需要从互联网上找到一个可以提供准确时间的服务器然后提供一种协议让我们同步自己的系统时间,这就涉及到了网络时间同步协议。

NTP 网络时间协议

网络时间协议,英文名称:Network Time Protocol(NTP)是用来使计算机时间同步化的一种协议,它可以使计算机对其服务器或时钟源(如石英钟,GPS等等)做同步化,它可以提供高精准度的时间校正(LAN上与标准间差小于1毫秒,WAN上几十毫秒),且可介由加密确认的方式来防止恶毒的协议攻击。NTP的目的是在无序的Internet环境中提供精确和健壮的时间服务.

Link 当前已提供的各国NTP服务器列表

网络时间协议并不是很轻松就能做好的,因为存在网络延迟,以及响应时间,比如我们连接了美国的NTP服务器,等到数据返回,已经5秒过去了,这些都存在问题,所以很多程序已经计算了传输时间差,来更准确的校准自己的时间。

NTP的网络时间协议,具有高精度,能精确到几十毫秒,但是算法很复杂,考虑到各种延迟啊,响应时间啊,而大多场景其实不需要这么高的精度,因此推出了-SMTP

SNTP 简单网络时间协议 (获取网络时间)

SNTP(Simple Network Time Protocol) 简化了NTP协议,同时也能保证时间达到一定的精确度。 我们平时使用的计算机的获取网络时间一说,大多都是使用的SNTP。这个协议依赖网络流量。

NTP和SNTP都是网络时间,可惜网络时间是没有地理信息的,我们需要自己手动配置时区。有同学会问:我们没有配置时区啊? 其实配置自己所在位置/国家 都是配置了时区

那么含有时区等信息的时间机制就出现了。

NITZ 网络标识和时区

NITZ(Network Identity and Time Zone)或网络标识和时区,是一种用于自动配置本地的时间和日期的机制,同时也通过无线网向移动设备提供运营商信息。我们Android手机中的网络时间获取,在有运营商的情况下,就使用的是NITZ,从运营商处获取时间,且不依赖流量,而且这个时间因为由基站提供,所以还包含了时区信息。这个时间大多数情况是准的,当然也会存在一些运营商提供的时间不准的情况。

作者:Anderson大码渣,欢迎关注我的简书: Anderson大码渣