总结 - Unix 纪元不止是个日期

toilet

前几日调整服务器缓存功能代码时为方便处理时间戳,存储时将日期时间转为秒数的整数格式,使用的编程语言是 Ruby 当时并不知晓这种存储方式是 Unix 世界早已通用的时间格式。

事后数据运维同事查看缓存说明文档时,反问时间戳的整数格式是否从格林尼治时间算起?鬼知道 Time.now.to_i 是怎么算的,走心的疑惑还有其他计算方式吗?无知的反问语里竟透露着焉敢质疑的咄咄逼人,久久不知如何解释。

Time#to_i

Returns the value of time as an integer number of seconds since the Epoch.

API 解释为从 Epoch 算起的总秒数,看着陌生的 Epoch 误以为是个专有名称,但英文再差还是有份自信它怎么也不会音译为格林尼治。

Epoch 时期; 纪元; 世; 新时代;

Epoch Time 指一个特定的时间:1970-01-01 00:00:00 UTC。

UTC 又是什么?

协调世界时(英:Coordinated Universal Time ,法:Temps Universel Coordonné),又称世界统一时间,世界标准时间,国际协调时间。英文(CUT)和法文(TUC)的缩写不同,作为妥协,简称UTC。

UTC 时间是以原子时秒长为基础,在时刻上尽量接近于世界时的一种时间计量系统,是新的标准时间。

新的标准时间?那旧标准时间的有那些?原来就是格林尼治时间。

格林尼治标准时间(Greenwich Mean Time,GMT)是指位于英国伦敦郊区的皇家格林尼治天文台的标准时间,本初子午线被定义为通过那里的经线。

由于地球每天的自转有些不规则,而且正在缓慢减速,因此,格林尼治时间已不再被作为标准时间使用。新的标准时间,是由原子钟报时的协调世界时(UTC)。

明白了 GMT/UTC 的标准时间方案更替的承接关系,那 1970 年发生了什么,以至于 Unix 系统以它作 “纪元”。

原来 Unix 就是在那个时代产生的,1969 年发布的雏形,最早是基于硬件 60Hz 的时间计数。

1971年底出版的《Unix Programmer's Manual》里定义的 Unix Time 是以 1971年1月1日00:00:00 作为起始时间,每秒增长 60。考虑到 32 位整数的范围,如果每秒 60 个数字,则两年半就会循环一轮,于是改成以秒为计数单位。循环周期有136年之长,就不在乎起始时间是 1970 还是 1971 年,遂改成人工记忆、计算比较方便的1970年。

看起来很乱的概念此时清晰很多,Unix 的世界开启了 “纪元”,Unix 时间戳也就成为了一个专有名称。

Unix 时间戳是一种时间表示方式,定义为从格林尼治时间 1970年01月01日 00时00分00秒 起至现在的总秒数,不考虑闰秒。

Unix 时间戳的英文称呼列表:

  • POSIX time
  • Epoch time
  • Unix epoch
  • Unix time
  • Unix timestamp

GMT/UTC 是两套时间标准;1970 年是 Unix 系统诞生的年代里易于人工记忆的年份;1970 年作为 Unix 系统历史长河中里程碑式的一年,正式开启了 Unix 世界的 “纪元”,番邦称 Epoch。

UTC 本质强调的是比 GMT 更为精确的世界时间标准,不过对于开发者而言,GMT 与 UTC 的功能与精确度是没有差别的。

HTTP 响应头中的日期就是使用旧款的 GMT 标准时间:

curl -I jianshu.com
HTTP/1.1 301 Moved Permanently
Server: Tengine
Date: Mon, 12 Dec 2016 14:29:05 GMT
Content-Type: text/html
Content-Length: 278
Connection: keep-alive
Location: http://www.jianshu.com/

MySQL

MySQL 不止是稳定好用存储数据的库,更是一套超强的工具集,生成与反解 Unix 时间戳的操作也只是一条命令的执行。

mysql> select unix_timestamp();
+------------------+
| unix_timestamp() |
+------------------+
|       1481545686 |
+------------------+
1 row in set (0.01 sec)

mysql> select from_unixtime(1481545686);
+---------------------------+
| from_unixtime(1481545686) |
+---------------------------+
| 2016-12-12 20:28:06       |
+---------------------------+
1 row in set (0.01 sec)

感兴趣的可以查询一下这两个函数,用法相当灵活,以便需要时脑中多一套解决思路,莫要有事没事就写脚本。

生长在天朝,配置数据库时除了中文编码外就是时间的设置,那么如何查看当前数据库是否按配置的时区在运行呢?

$ cat /ect/my.cnf
[mysqld]
default_time_zone='+08:00'
mysql> select timediff(now(), utc_timestamp) as date_area;
+-----------+
| date_area |
+-----------+
| 08:00:00  |
+-----------+
1 row in set (0.00 sec)

mysql> select utc_timestamp();
+---------------------+
| utc_timestamp()     |
+---------------------+
| 2016-12-12 13:51:15 |
+---------------------+
1 row in set (0.00 sec)

mysql> select current_timestamp();
+---------------------+
| current_timestamp() |
+---------------------+
| 2016-12-12 21:50:38 |
+---------------------+
1 row in set (0.00 sec)

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2016-12-12 21:50:49 |
+---------------------+
1 row in set (0.00 sec)

MySQL# UTC_TIMESTAMP

Returns the current UTC date and time as a value in 'YYYY-MM-DD HH:MM:SS' or YYYYMMDDHHMMSS format, depending on whether the function is used in a string or numeric context.

UTC 标准时间按指定的格式显示,那么还有其他的显示格式?查询 API 果然无规矩不成方圆,发现真有个函数可以获取不同标准时间的显示格式,自己过于肤浅,这才意示到优秀的工具中随便显示的时间格式都是各有出处。

mysql> select get_format(datetime,'iso') as iso;
+-------------------+
| iso               |
+-------------------+
| %Y-%m-%d %H:%i:%s |
+-------------------+
1 row in set (0.01 sec)

显示格式的标准不多,贴一下权当备忘:

Function Call Result
GET_FORMAT(DATE,'USA') '%m.%d.%Y'
GET_FORMAT(DATE,'JIS') '%Y-%m-%d'
GET_FORMAT(DATE,'ISO') '%Y-%m-%d'
GET_FORMAT(DATE,'EUR') '%d.%m.%Y'
GET_FORMAT(DATE,'INTERNAL') '%Y%m%d'
GET_FORMAT(DATETIME,'USA') '%Y-%m-%d %H.%i.%s'
GET_FORMAT(DATETIME,'JIS') '%Y-%m-%d %H:%i:%s'
GET_FORMAT(DATETIME,'ISO') '%Y-%m-%d %H:%i:%s'
GET_FORMAT(DATETIME,'EUR') '%Y-%m-%d %H.%i.%s'
GET_FORMAT(DATETIME,'INTERNAL') '%Y%m%d%H%i%s'
GET_FORMAT(TIME,'USA') '%h:%i:%s %p'
GET_FORMAT(TIME,'JIS') '%H:%i:%s'
GET_FORMAT(TIME,'ISO') '%H:%i:%s'
GET_FORMAT(TIME,'EUR') '%H.%i.%s'
GET_FORMAT(TIME,'INTERNAL') '%H%i%s'

Terminal

若在数据库中操作,使用上述函数已经可以随手生成、解析 Unix 时间戳,若未在数据库中操作,难不成为查看 Unix 时间戳还要再登录数据库?打开命令终端,也是一个命令分秒间释然的事情。

$ uname -s
Darwin
$ date +%s
1481546766
$ date -r 1481546766
2016年12月12日 星期一 20时46分06秒 CST

$ cat /etc/redhat-release
CentOS release 6.5 (Final)
$ date +%s
1481546890
$ date -d @1481546890
2016年 12月 12日 星期一 20:48:10 CST

$ irb
irb(main):001:0> t = Time.now.to_i
=> 1481547158
irb(main):002:0> Time.at(t)
=> 2016-12-12 20:52:38 +0800

> window.userAgent
< "mozilla/5.0 (macintosh; intel mac os x 10_10_5) applewebkit/601.7.7 (khtml, like gecko) version/9.1.2 safari/601.7.7"
> var t = Math.round(new Date().getTime() / 1000)
< undefined
> t
< 1481601053
> new Date(t * 1000)
< Tue Dec 13 2016 11:50:53 GMT+0800 (CST) 

CST 又是什么时间标准?CST 可视为美国、澳大利亚、古巴或中国的标准时间,可为如下 4 个不同时区的缩写:

  • 古巴标准时间:Cuba Standard Time UT-4:00
  • 中国标准时间:China Standard Time UT+8:00
  • 美国中部时间:Central Standard Time (USA) UT-6:00
  • 澳大利亚中部时间:Central Standard Time (Australia) UT+9:30

简单查找资料未找到 CST 存在的意义,仅仅是上述几行文字的解释。TODO: CST 产生的原因

参考列表中 百科:Unix时间戳 值得简单阅读,内有彩蛋。

其他标准时间

CET(Central European Time,CET)欧洲中部时间是比世界标准时间(UTC)早一个小时的时区名称之一。

它被大部分欧洲国家和部分北非国家采用。

冬季时间为 UTC + 1,夏季欧洲夏令时为 UTC + 2。

DST (Daylight Saving Time)夏日节约时间,指在夏天太阳升起的比较早时,将时钟拨快一小时,以提早日光的使用,在英国则称为夏令时间(Summer Time)。

这个构想于 1784年由美国班杰明·富兰克林提出来,1915 年德国成为第一个正式实施夏令日光节约时间的国家,以削减灯光照明和耗电开支。自此以后,全球以欧洲和北美为主的约 70 个国家都引用了这个套方案。

欧洲手机上也有很多 GSM 系统的基地台,除了会传送当地时间外也包括夏令日光节约时间,做为手机的时间标准,使用者可以自行决定开启或关闭。

值得注意的是,某些国家有实施「夏日节约时间」的制度,出国时别忘了跟随当地习惯在表上调整一下,这可是机械表没有的功能设计!

各标准时间的计算

  • UTC = GMT
  • CET = UTC/GMT + 1
  • CST = UTC/GMT + 8
  • CST = CET + 9

参考

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容