时间的标准与格式
时间的标准与格式
GMT(格林威治标准时间)
格林威治(又译格林尼治)它是一个位处英国伦敦的小镇。
17 世纪,英国航海事业发展迅速,当时海上航行亟需精确的精度指示,于是英国皇家在格林威治这个地方设立了一个天文台负责测量正确经度的工作。
后来 1884 年,在美国华盛顿召开的国际经度会以决定以经过格林尼治天文台(旧址) 的经线为本初子午线(0 度经线)。同时这次会以也将全球划分为了 24 个时区。0 度经线所 在的时区为 0 时区。
现在,有时候你要买一个机械表,如果它说支持 GMT,意思就是支持显示格林威治标准时间。
UT(世界时)
1928 年,国际天文联合会提出了 UT 的概念,UT 主要用来衡量一天究竟有多长。一旦 一天的长度可以确定,那么将这个长度除以 24 就能确定一小时的长度。以此类推、分钟、 秒的长度我们就都能确定了。
UT 也是以格林威治时间作为标准的,它规定格林威的子夜为 0 点。
在当时,衡量一天长度的方法就是通过天文观测,看地球多久转一圈。但一来天文观 测存在误差。二来,地球的自转越来越慢。计时方法亟需革新。
计时技术与国际原子时
人类历史上出现的计时手段大体上能分为三类
- 一是试图通过某种匀速的运动来表示时间、比如沙漏、水钟、香钟(烧香)。这种方 式的缺陷很大,是一种很粗略的时间衡量方法
- 二是通过天文观测,通过日月或其他星辰的参考确定时间。现在我们已经知道,星 系的运动也不是匀速的过程。
- 三是通过固定频率的震动,最早是伽利略通过教堂的吊灯发现了摆的等时性,也就 是摆角较小时,吊灯摆动一次的时间是相同的。距今三四百年前的摆钟,基本上都是利用 这一原理实现的。
现在,人类已知的最精确的计时技术是原子钟,它以原子共振频率标准来计算和保持 时间的准确。它的精度可以达到持续运行上亿年而误差不超过 1 秒。
基于这种技术,后来国际计量协会结合了全球 400 多个原子钟,规定 1 秒为铯-133 原子基态两个超精细能级间跃迁辐射震荡 9,192,631,770 周所持续的时间。这个定义就叫国际 原子时(International Atomic Time, TAI)。这样,我们钟表里指针应该转多快也有了一个 统一的标准。
国际原子时的秒长以格林威治时间 1958 年 1 月 1 日 0 时的秒长为基准。也就是规定, 在这一瞬间,国际原子时的秒长和世界时的秒长是一样的。
UTC(世界协调时)
UTC,universal Time Coordinated。世界协调时,世界统一时间、国际协调时。它以国 际原子时的秒长为基准。但是我们知道,UT 基于天文观测,地球越来越慢那 UT 的秒长应 该越来越长。如果不进行干预那么 UTC 和 UT 之间就会有越来也大的误差。
如果这种状况持续下去,在好多好多好多好多年后,人类可能就是 UTC 时间凌晨 3 点 起床挤地铁上班了。因此,让 UTC 符合人类生活习惯,就必须控制 UTC 和 UT 的误差大 小,于是 UTC 引入了闰秒。所谓闰秒,也就是让在某个时间点上,人为规定这一分钟比普 通的分钟多一秒,它有 61 秒。这个时候 1 分 59 秒过了应该接着是 2 分 0 秒,但是在遇到 闰秒时会遇到 1 分 60 秒。
看似好像也能接受。但是何时加入闰秒是不可预测的。它是由国际地球自转服务 (IERS)每隔一段时间依据实际情况决定的。对计算机的程序而言,闰秒机制具有明显的 破坏性,相关国际标准机构一直在讨论是否继续这种做法。
小结:UTC/GMT
- GMT 是最早的国际时间标准,后来是 UTC
- 因为 UTC 要逼近 UT,而 UT 又以 GMT 为标准。十分严格地说,UTC 和 GMT 不是 一个东西。但宽松地说,你可以把 UTC 等同于 GMT,而且有些网站和应用程序就是这么 干的。
- 因为 UTC 标准已经使用多年。所以现在如果再看到 GMT 这个词,它指的通常不是 国际时间,而是格林威治所在的时区,也就是 0 时区。同时,通常行政区有很多适应自己 所在地的时区缩写,遗憾的是,这种写法经常会撞车。
比如,CCT,它可以表示美国中部时间(Central Standard Time),澳大利亚中部时间 (Central Standard Time),中国标准时间(China Standard Time)和古巴标准时间(Cuba Standard Time)
所以、如果我写 CCT 2022-08-03 11:56 就很容易误解了。这个时候我们非常需要一种 没有歧义的日期时间写法。
时区与 UTC 偏移量
现行的时区表示更多是使用 UTC+偏移量的方式来表示的。比如北京是在东 8 区,时 间比 UTC 要早 8 小时,那么在表示北京时区的方式就是 UTC+08:00。虽然地理界定上只有 东西十二区,但是什么地方采用什么方式表达时间实际取决于当地的行政命令。因此 UTC+12:00 并不是偏移量的上限。打开你电脑上的日期时间设置,你会发现有的的国家采用的是 UTC+14:00。还有的国家偏移量并不完全是小时的整数倍,比如 UTC+12:45。同时,也有很多应用会使用 GMT+0800 的方式表示,效果是一样的。
日期时间的表示格式
2022 年 9 月 3 日该怎么表示?是 2022/09/03 还是 2022-09-03 还是 Sep 03 2022 ?这又 是一个标准问题,当前的情况是,各个国家有符合本地习惯的日期时间格式标准,同时国 际上也有诸多日期时间格式标准,比如 ISO 8601 和 RFC3339 等。
各种格式都有软件采用,所以编程语言中的日期标准库,一般都会准备 dateformat 工 具,自己编码日期时间的格式。
ISO 8601
国际标准 ISO 8601,是国际标准化组织的日期和时间的表示方法和我们之前提过的 UTC 不同,UTC 是一种时间标准,而 ISO 8601 是一种标准的时间格式,大多数的编程语 言都支持。
使用 ISO 8601 格式可以明确表示下面的时间。
- 公历日期
- 24 小时制的时间
- UTC 时区偏移量
- 时间间隔
- 以及上面几种元素的组合。
ISO 8601 的表示非常灵活,这里不会将其完全列出,我们直说最常见的日期时间格式。
比如,下面就是一个符合 ISO 8601 的日期时间表示。
2022-09-03T14:13:00Z,这个时间戳中间的 T 用来分隔 日期 和 时间,最后字母 Z 表示 0 时区,也就是 UTC 或 GMT 时间。
在编程语言中获取 UTC 时间和 ISO 格式
x = new Date()
x.toISOString()
RFC 3339
RFC 是 request for comment 的简写。它其实是一系列加了编号的文件。这一系列文件 收集了有关互联网的文章,包括 UNIX 和某些互联网社区上的软件文件。RFC 还收录了很 多与互联网标准相关的文章,包含各种网络协议,以及我们今天要谈及的时间格式标准问 题。
RFC3339 这篇文章的原文标题叫作,Date and Time on the Internet:Timestamps(互联 网上的日期和时间:时间戳),发表的时间是 2002 年 7 月。感兴趣的同学可以参考原文: https://www.rfc-editor.org/rfc/rfc3339
简单来说 RFC3339 对日期时间的定义更加简洁,去掉了 ISO 8601 中一些小众的表达 方式,也更具有可读性。
RFC3339 和 ISO8601 之间的关系
可以参考:https://ijmacd.github.io/rfc3339-iso8601/
这个网站可以实时展示当前时间的 RFC3339 表示和 ISO 8601 表示。下面这张图是它 的截图。可以看到 RFC 3339 的表述有一部分和 ISO 8601 是相同的。
仔细去看你会发现,RFC3339 格式的日期时间表述,基本上都能第一时间反应出来它 表述的是什么时间。而 ISO 8601 中就会有像 2022-242T16:55:17/PT3H 这种看上去奇奇怪怪 的表述。
Unix 时间戳与闰秒
什么是 Unix 时间戳
Unix 时间戳是一种将时间跟踪为运行总秒数的方法,这个技术从 1970 年 1 月 1 日的 UTC 开始。因此,Unix 时间戳只表示从特定时间点到现在的秒数。而且,需要注意的是, 无论你身处何,这个总秒数的值在技术上都不会发生改变。所以这对计算机系统,客户端 和服务端的通信和日期跟踪十分有用。
Unix 时间戳是怎么处理闰秒的
关于闰秒问题,我们之前说过,什么时候出现闰秒是不确定的。那么在 Unix 时间戳里, 是怎么处理闰秒的呢?答案是减慢时钟。
[root@influxdb ~]# date -d '@867715199'
1997年 07月 01日 星期二 07:59:59 CST
[root@influxdb ~]# date -d '@867715200'
1997年 07月 01日 星期二 08:00:00 CST
比如 1997 年 6 月 30 日 23:59:59 到 1997 年 7 月 1 日 00:00:00 应该发生一次闰秒。
那么 867715200 这个时间戳应该对应 1997 年 6 月 30 日的 23:59:60。但是 Linux 好像压 根不知道这件事。这是因为 Unix 时间戳标准里,把一天定死为 86400 秒了。所以类 Unix 的处理方案是,当闰秒发生时由 ntrp 服务把时钟慢下来,当时间戳为 867715199 的时候, 让它在这个值上多停留 1 秒然后再进入 867715200。