Unix Time 的几个冷门知识点
unix time
许多人对 unix time有误解,只知其是相对世界时/格林威治时1970年1月1号0点0分0秒整的时间差,有的人可能还记得是0时区。
但这些认识是不对的。而一些文档如Java API Doc里写的并不全,或没有明确使阅读者明确理解。
笔者工作过程就曾经听到不同的人在做把unix timestamp 转化为格式化的时间时,会问时区是哪里的,或者认为其时区是本地或者0时区的是否+8。
排除这种误区实际上可以简单的记住一点即可:unix timestamp 是 相对于 UTC 时间的时间差,而 UTC 几乎是对等 GMT+0 的时间。
概念
先从Wikipedia介绍几个概念:
世界时(Universal Time,简称UT)是一种以格林尼治子夜起算的平太阳时。世界时是以地球自转为基准得到的时间尺度,其精度受到地球自转不均匀变化和极移的影响,为了解决这种影响,1955年国际天文联合会定义了UT0、UT1和UT2:
1. UT0系统是由一个天文台的天文观测直接测定的世界时,没有考虑极移造成的天文台地理坐标变化。该系统曾长期被认为是稳定均匀的时间计量系统,得到过广泛应用。
2. UT1系统是在UT0的基础上加入了极移改正 Δλ,修正地轴摆动的影响。UT1是目前使用的世界时标准。被作为目前世界民用时间标准UTC在增减闰秒时的参照标准。
3. UT2系统是UT1的平滑处理版本,在UT1基础上加入了地球自转速率的季节性改正 ΔT。
协调世界时(英语:Coordinated Universal Time,法语:Temps Universel Coordonné,简称UTC)是最主要的世界时间标准,其以原子时秒长为基础,在时刻上尽量接近于格林威治标准时间
格林尼治平均时间(英语:Greenwich Mean Time,GMT)是指位于英国伦敦郊区的皇家格林尼治天文台当地的平太阳时,因为本初子午线被定义为通过那里的经线。
Unix epoch:that is the time 00:00:00 UTC on 1 January 1970,即一般指特定的时间:1970-01-01 00:00:00 UTC。
Unix time:also known as Epoch time, POSIX time,seconds since the Epoch,or UNIX Epoch time.It is the number of seconds that have elapsed since the Unix epoch, minus leap seconds. Leap seconds are ignored,with a leap second having the same Unix time as the second before it, and every day is treated as if it contains exactly 86400 seconds.[2] Due to this treatment, Unix time is not a true representation of UTC.
上述,UTC是协调世界时,即Universal Time Coordinated,英法两国联合定制,名字取二者调和。
上述,Unix time表示距离unix Epoch的秒数,但Unix time是不考虑闰秒的,这意味着如果你运行:
1) JAVA的System.out.println(new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss,SSS”).format(915148800750l));
系统输出的是 1999-01-01 08:00:00,750
2) 或python的 datetime.datetime.fromtimestamp(915148800.750).strftime(“%Y-%m-%d %H:%M:%S.%f”)
系统输出的是:1999-01-01 08:00:00.750000
但实际上 UTC时间 其实是 1998-12-31T23:59:60.75,而不是1999年1月1日。
地球的轨道和运动速度都不是均匀的,天文学家计算地球非圆形轨迹与极轴倾斜对视太阳时的效应,修正以后的实际即平太阳时,在格林尼治子午线上的平太阳时称为世界时(UT0),又叫格林尼治平时(GMT),为了兼容人们对天亮/天黑的常识(如正午12点表示太阳正当中),地球相应划分24个时区。
协调时是一个时间刻度标准,GMT是一个刻度,UTC即GMT+0,只是后来协调时的基准是原子钟,也就和GMT不相干了,虽然二者可能差距不过1秒。现在GMT时间已不再被科学界所使用,尽管GMT可转换为UTC。
但协调世界时和相差不会超过0.9秒,有需要时便会在协调世界时内加上正或负闰秒。因此协调世界时与国际原子时(TAI)之间会出现若干整数秒的差别。位于巴黎的国际地球自转事务中央局(IERS)负责决定何时加入闰秒。
在UTC系统的时间尺度中,秒和比秒小的单位(毫秒、微秒等)其长度是固定的,但是对于分钟和比分还大的单位(小时、天、周等),其长度是可变的。国际地球自转服务组织(IERS)做出插入闰秒的决定,并至少在加入前6个月发布在该组织的“公告C”中。闰秒是无法提前很早预知的,因为地球的自转速率是不可预测的。几乎所有的UTC天都包含 86,400 SI秒,即每分钟正好有60秒。
然而,由于一个平太阳日比 86,400 SI秒稍微长一些,偶尔会有一个UTC天的最后一分钟被调整为61秒。多出的这一秒被称为闰秒,它体现了上一闰秒后比平太阳日多出来的全部时长(大约每天2毫秒)。一个UTC天的最后一分钟也可以是59秒,以此来适应地球自转得更快的情况,但是这样的可能性很小,至今还没有出现过。UTC天的长度不规则意味着带小数的儒略日和UTC时间不能很好的对应。
为了保证协调世界时很接近世界时UT1,UTC从基于TAI的线性方程转变成另一方程时,偶尔会出现不连续点。这些不连续点以闰秒的形式体现出来,这些不连续点就是造成了UTC天的长度不规则的闰秒。IERS规定不连续点仅出现在6月或12月底,但也有规定将3月或者9月作为备选。国际地球自转服务组织(IERS)跟踪并公布UTC时间和世界时的差别,即DUT1 = UT1 - UTC,另外,IERS也负责引入不连续的闰秒来保证它们的时间差DUT1在±0.9秒之间
NTP就是基于世界协调时的,北京时间即是 UTC+8 的。
其他
对了,计算机是怎么计算时间的,像Java的System.currenTimeMillis怎么获取Unix时间呢?
一般商用/办公/家用计算机主板上有计时电路,核心是晶体振荡器,靠电池供电维持一定频率的震荡,转化为时钟信号,无电量或电量不足就会归零或慢,此外这个信号频率不够稳定,受环境压力/温度影响,时间并不准确,所以通常会通过网络较时来修正。
但这个频率还不足以纳秒级别,像Java的System.nanoTime是需要高频的(1GHz),其实就是CPU内部电路产生的脉冲频率。
对于牛顿力学而言,摆钟的周期实际受重力影响,所以摆钟走时是不准的,而我们本身佩戴的机械手表同样受重力/摩擦力/气压/游丝重心/摆轮平衡等影响,据说世界上曾最精准的依赖石英震动的机械表每天误差千分之一秒,而如今大众佩戴的机械表如陀飞轮/defy等也只能每天0.25秒差异。
说因为相对论影响,机械钟测量不准而采用本20世纪发现的原子钟实际上不正确。
科学家们发现原子的能级跃迁释放电磁波,这种电磁波的频率是恒定的,通过一系列放大效应,人们就可以将其作为时间脉冲的节拍器,只不过这种节拍器最小可以做到每秒钟10^15次方次计数,然后逐层放大到秒/分钟等。原子钟不受气压/温度等影响,但其实是受重力影响的,曾有试验做过,飞行原子钟来回后和地球原子钟存在差异(微秒级别),这其实才是需要用相对论,而且是广义相对论解释了(时间膨胀)。
而现有的原子钟精确到 50亿年误差一秒,比地球年龄要大,可以认为是精度极高。
Ref
Unix time
https://en.wikipedia.org/wiki/Unix_time
时间膨胀
https://zh.wikipedia.org/wiki/%E6%99%82%E9%96%93%E8%86%A8%E8%84%B9
原子钟
https://baike.baidu.com/item/%E5%8E%9F%E5%AD%90%E9%92%9F/765460
最精确原子钟问世,50亿年误差一秒
https://tech.qq.com/a/20141105/008961.htm
一些语言的时间范围
https://zh.wikipedia.org/wiki/%E7%B3%BB%E7%BB%9F%E6%97%B6%E9%97%B4
讲了这么多年的CPU频率,到底是什么?
https://zhuanlan.zhihu.com/p/30582175