總結 - 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.lxweimin.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閱讀 230,431評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,637評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,555評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,900評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,629評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,976評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,976評論 3 448
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,139評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,686評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,411評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,641評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,129評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,820評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,233評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,567評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,362評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,604評論 2 380

推薦閱讀更多精彩內容