前幾日調(diào)整服務(wù)器緩存功能代碼時為方便處理時間戳劳坑,存儲時將日期時間轉(zhuǎn)為秒數(shù)的整數(shù)格式铺厨,使用的編程語言是 Ruby 當(dāng)時并不知曉這種存儲方式是 Unix 世界早已通用的時間格式。
事后數(shù)據(jù)運(yùn)維同事查看緩存說明文檔時窍株,反問時間戳的整數(shù)格式是否從格林尼治時間算起?鬼知道 Time.now.to_i
是怎么算的攻柠,走心的疑惑還有其他計算方式嗎球订?無知的反問語里竟透露著焉敢質(zhì)疑的咄咄逼人,久久不知如何解釋瑰钮。
Time#to_i
Returns the value of time as an integer number of seconds since the Epoch.
API 解釋為從 Epoch 算起的總秒數(shù)冒滩,看著陌生的 Epoch 誤以為是個專有名稱,但英文再差還是有份自信它怎么也不會音譯為格林尼治浪谴。
Epoch 時期; 紀(jì)元; 世; 新時代开睡;
Epoch Time 指一個特定的時間:1970-01-01 00:00:00 UTC因苹。
UTC 又是什么?
協(xié)調(diào)世界時(英:Coordinated Universal Time 篇恒,法:Temps Universel Coordonné)扶檐,又稱世界統(tǒng)一時間,世界標(biāo)準(zhǔn)時間胁艰,國際協(xié)調(diào)時間款筑。英文(CUT)和法文(TUC)的縮寫不同,作為妥協(xié)腾么,簡稱UTC奈梳。
UTC 時間是以原子時秒長為基礎(chǔ),在時刻上盡量接近于世界時的一種時間計量系統(tǒng)解虱,是新的標(biāo)準(zhǔn)時間攘须。
新的標(biāo)準(zhǔn)時間?那舊標(biāo)準(zhǔn)時間的有那些殴泰?原來就是格林尼治時間阻课。
格林尼治標(biāo)準(zhǔn)時間(Greenwich Mean Time,GMT)是指位于英國倫敦郊區(qū)的皇家格林尼治天文臺的標(biāo)準(zhǔn)時間艰匙,本初子午線被定義為通過那里的經(jīng)線限煞。
由于地球每天的自轉(zhuǎn)有些不規(guī)則,而且正在緩慢減速员凝,因此署驻,格林尼治時間已不再被作為標(biāo)準(zhǔn)時間使用。新的標(biāo)準(zhǔn)時間健霹,是由原子鐘報時的協(xié)調(diào)世界時(UTC)旺上。
明白了 GMT/UTC 的標(biāo)準(zhǔn)時間方案更替的承接關(guān)系,那 1970 年發(fā)生了什么糖埋,以至于 Unix 系統(tǒng)以它作 “紀(jì)元”宣吱。
原來 Unix 就是在那個時代產(chǎn)生的,1969 年發(fā)布的雛形瞳别,最早是基于硬件 60Hz 的時間計數(shù)征候。
1971年底出版的《Unix Programmer's Manual》里定義的 Unix Time 是以 1971年1月1日00:00:00 作為起始時間,每秒增長 60祟敛“贪樱考慮到 32 位整數(shù)的范圍,如果每秒 60 個數(shù)字馆铁,則兩年半就會循環(huán)一輪跑揉,于是改成以秒為計數(shù)單位。循環(huán)周期有136年之長,就不在乎起始時間是 1970 還是 1971 年历谍,遂改成人工記憶现拒、計算比較方便的1970年。
看起來很亂的概念此時清晰很多望侈,Unix 的世界開啟了 “紀(jì)元”印蔬,Unix 時間戳也就成為了一個專有名稱。
Unix 時間戳是一種時間表示方式甜无,定義為從格林尼治時間 1970年01月01日 00時00分00秒 起至現(xiàn)在的總秒數(shù)扛点,不考慮閏秒。
Unix 時間戳的英文稱呼列表:
- POSIX time
- Epoch time
- Unix epoch
- Unix time
- Unix timestamp
GMT/UTC 是兩套時間標(biāo)準(zhǔn)岂丘;1970 年是 Unix 系統(tǒng)誕生的年代里易于人工記憶的年份陵究;1970 年作為 Unix 系統(tǒng)歷史長河中里程碑式的一年,正式開啟了 Unix 世界的 “紀(jì)元”奥帘,番邦稱 Epoch铜邮。
UTC 本質(zhì)強(qiáng)調(diào)的是比 GMT 更為精確的世界時間標(biāo)準(zhǔn),不過對于開發(fā)者而言寨蹋,GMT 與 UTC 的功能與精確度是沒有差別的松蒜。
HTTP 響應(yīng)頭中的日期就是使用舊款的 GMT 標(biāo)準(zhǔn)時間:
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.reibang.com/
MySQL
MySQL 不止是穩(wěn)定好用存儲數(shù)據(jù)的庫,更是一套超強(qiáng)的工具集已旧,生成與反解 Unix 時間戳的操作也只是一條命令的執(zhí)行秸苗。
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)
感興趣的可以查詢一下這兩個函數(shù),用法相當(dāng)靈活运褪,以便需要時腦中多一套解決思路惊楼,莫要有事沒事就寫腳本。
生長在天朝秸讹,配置數(shù)據(jù)庫時除了中文編碼外就是時間的設(shè)置檀咙,那么如何查看當(dāng)前數(shù)據(jù)庫是否按配置的時區(qū)在運(yùn)行呢?
$ 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 標(biāo)準(zhǔn)時間按指定的格式顯示璃诀,那么還有其他的顯示格式弧可?查詢 API 果然無規(guī)矩不成方圓,發(fā)現(xiàn)真有個函數(shù)可以獲取不同標(biāo)準(zhǔn)時間的顯示格式劣欢,自己過于膚淺棕诵,這才意示到優(yōu)秀的工具中隨便顯示的時間格式都是各有出處。
mysql> select get_format(datetime,'iso') as iso;
+-------------------+
| iso |
+-------------------+
| %Y-%m-%d %H:%i:%s |
+-------------------+
1 row in set (0.01 sec)
顯示格式的標(biāo)準(zhǔn)不多氧秘,貼一下權(quán)當(dāng)備忘:
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
若在數(shù)據(jù)庫中操作年鸳,使用上述函數(shù)已經(jīng)可以隨手生成、解析 Unix 時間戳丸相,若未在數(shù)據(jù)庫中操作,難不成為查看 Unix 時間戳還要再登錄數(shù)據(jù)庫彼棍?打開命令終端灭忠,也是一個命令分秒間釋然的事情膳算。
$ 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 又是什么時間標(biāo)準(zhǔn)?CST 可視為美國弛作、澳大利亞涕蜂、古巴或中國的標(biāo)準(zhǔn)時間,可為如下 4 個不同時區(qū)的縮寫:
- 古巴標(biāo)準(zhǔn)時間:Cuba Standard Time UT-4:00
- 中國標(biāo)準(zhǔn)時間:China Standard Time UT+8:00
- 美國中部時間:Central Standard Time (USA) UT-6:00
- 澳大利亞中部時間:Central Standard Time (Australia) UT+9:30
簡單查找資料未找到 CST 存在的意義映琳,僅僅是上述幾行文字的解釋机隙。TODO: CST 產(chǎn)生的原因
參考列表中 百科:Unix時間戳 值得簡單閱讀,內(nèi)有彩蛋萨西。
其他標(biāo)準(zhǔn)時間
CET(Central European Time有鹿,CET)歐洲中部時間是比世界標(biāo)準(zhǔn)時間(UTC)早一個小時的時區(qū)名稱之一。
它被大部分歐洲國家和部分北非國家采用谎脯。
冬季時間為 UTC + 1葱跋,夏季歐洲夏令時為 UTC + 2。
DST (Daylight Saving Time)夏日節(jié)約時間源梭,指在夏天太陽升起的比較早時娱俺,將時鐘撥快一小時,以提早日光的使用废麻,在英國則稱為夏令時間(Summer Time)荠卷。
這個構(gòu)想于 1784年由美國班杰明·富蘭克林提出來,1915 年德國成為第一個正式實施夏令日光節(jié)約時間的國家烛愧,以削減燈光照明和耗電開支油宜。自此以后,全球以歐洲和北美為主的約 70 個國家都引用了這個套方案屑彻。
歐洲手機(jī)上也有很多 GSM 系統(tǒng)的基地臺验庙,除了會傳送當(dāng)?shù)貢r間外也包括夏令日光節(jié)約時間,做為手機(jī)的時間標(biāo)準(zhǔn)社牲,使用者可以自行決定開啟或關(guān)閉粪薛。
值得注意的是,某些國家有實施「夏日節(jié)約時間」的制度搏恤,出國時別忘了跟隨當(dāng)?shù)亓?xí)慣在表上調(diào)整一下违寿,這可是機(jī)械表沒有的功能設(shè)計!
各標(biāo)準(zhǔn)時間的計算
- UTC = GMT
- CET = UTC/GMT + 1
- CST = UTC/GMT + 8
- CST = CET + 9