UTC 相關(guān)概念的理解 JavaScript 里的 Date 筆記

筆記分成兩部分:1、與 UTC 相關(guān)的一些概念的理解;2、JavaScript 里的 Date 類型

在引用中文維基百科基礎(chǔ)上,加一點(diǎn)自己對(duì)此的理解,介紹一下 UTC 以及與之相關(guān)的一系列其他的術(shù)語的概念:時(shí)標(biāo)、UT、TAI、GMT,希望能通俗易懂的同時(shí)也不至于繆人千里(有錯(cuò)誤的地方歡迎指正):

  • 時(shí)標(biāo):時(shí)標(biāo)指的是一種將時(shí)間分配到事件的機(jī)制,通過某些事件的發(fā)生我們可以確定對(duì)應(yīng)的時(shí)間?,F(xiàn)時(shí)有兩類時(shí)標(biāo)被廣泛應(yīng)用,一種是「基于天文學(xué)」的,這個(gè)我們可能比較熟,比方說現(xiàn)在時(shí)間是 2018 年 7 月 24 日 12 點(diǎn)整,太陽在我們正頭頂,等到下一次太陽在我們正頭頂?shù)臅r(shí),那我們知道這個(gè)時(shí)候距離上次過了一天,時(shí)間應(yīng)該就是 2018 年 7 月 25 日 12 點(diǎn)整;另一種是基于「原子振動(dòng)頻率」的,也舉個(gè)例子,比如我們知道某個(gè)原子振動(dòng)發(fā)生躍遷輻射 XXX(某個(gè)整數(shù)) 個(gè)周期的時(shí)間剛好是 1 秒,現(xiàn)在時(shí)間是 2018 年 7 月 24 日 12 點(diǎn)整,我們讓這個(gè)原子開始振動(dòng),并開始記錄,當(dāng)記錄振動(dòng)了 XXX * 3600 個(gè)周期后我們可以知道這個(gè)時(shí)候距離剛才過了 1 個(gè)小時(shí),那么此時(shí)時(shí)間就是 2018 年 7 月 24 日 13 點(diǎn)整。下面說的 UT、GMT、TAI、UTC 都是一種時(shí)標(biāo)。后面相關(guān)的內(nèi)容基本出自中文維基百科。
  • UT(Universal Time,世界時(shí)):是一種以格林尼治子夜起算的平太陽時(shí)。世界時(shí)是以地球自轉(zhuǎn)為基準(zhǔn)得到的時(shí)間尺度,其精度受到地球自轉(zhuǎn)不均勻變化和極移的影響,為了解決這種影響,1955年國(guó)際天文聯(lián)合會(huì)定義了UT0、UT1和UT2三個(gè)系統(tǒng):
    • UT0 系統(tǒng)是由格林尼治天文臺(tái)的天文觀測(cè)直接測(cè)定的世界時(shí),沒有考慮極移造成的天文臺(tái)地理坐標(biāo)變化。該系統(tǒng)曾長(zhǎng)期被認(rèn)為是穩(wěn)定均勻的時(shí)間計(jì)量系統(tǒng),得到過廣泛應(yīng)用。
    • UT1系統(tǒng)是在UT0的基礎(chǔ)上加入了極移改正 Δλ,修正地軸擺動(dòng)的影響。UT1是目前使用的世界時(shí)標(biāo)準(zhǔn)。被作為目前世界民用時(shí)間標(biāo)準(zhǔn)UTC在增減閏秒時(shí)的參照標(biāo)準(zhǔn)。
    • UT2系統(tǒng)是UT1的平滑處理版本,在UT1基礎(chǔ)上加入了地球自轉(zhuǎn)速率的季節(jié)性改正 ΔT。
  • GMT(Greenwich Mean Time,格林尼治平時(shí)):格林尼治平時(shí)的正午是指當(dāng)平太陽橫穿格林尼治子午線時(shí)(也就是在格林尼治上空最高點(diǎn)時(shí))的時(shí)間。由于地球每天的自轉(zhuǎn)是有些不規(guī)則的,而且正在緩慢減速,因此格林尼治平時(shí)基于天文觀測(cè)本身的缺陷,已經(jīng)被原子鐘報(bào)時(shí)的協(xié)調(diào)世界時(shí)(UTC)所取代。GTM 可以看成與 UT0 一回事。
  • TAI(International Atomic Time,國(guó)際原子時(shí)):是根據(jù)以下秒的定義的一種國(guó)際參照時(shí)標(biāo),屬于國(guó)際單位制。
    秒的定義:1967年第13屆國(guó)際計(jì)量大會(huì)上通過一項(xiàng)決議,定義一秒為銫-133 原子基態(tài)兩個(gè)超精細(xì)能級(jí)間躍遷輻射 9,192,631,770 周所持續(xù)的時(shí)間。其起點(diǎn)為世界時(shí)1958年的開始。就是說,銫-133 原子基態(tài)兩個(gè)超精細(xì)能級(jí)間躍遷開始輻射這件事發(fā)生,到它們輻射上面那么多周期這件事發(fā)生時(shí),這兩件事發(fā)生的間隔的度量就定義為 1 秒的長(zhǎng)度。
  • UTC(Coordinated Universal Time,協(xié)調(diào)世界時(shí)):協(xié)調(diào)世界時(shí)是世界上調(diào)節(jié)時(shí)鐘和時(shí)間的主要時(shí)間標(biāo)準(zhǔn)?;趪?guó)際原子時(shí),并通過不規(guī)則的加入閏秒來抵消地球自轉(zhuǎn)變慢的影響。閏秒在必要的時(shí)候會(huì)被插入到 UTC 中,以保證協(xié)調(diào)世界時(shí)(UTC)與世界時(shí)(UT1)相差不超過0.9秒。就是說現(xiàn)在日常生活中我們都是以這個(gè)時(shí)間為準(zhǔn)的,比如我們戴的機(jī)械表可能會(huì)找手機(jī)或者電腦上的時(shí)間來對(duì),那手機(jī)、電腦上的時(shí)間又是怎么來的呢?在聯(lián)網(wǎng)的時(shí)候,手機(jī)和電腦會(huì)定期向系統(tǒng)預(yù)置的某個(gè)服務(wù)器地址請(qǐng)求時(shí)間同步,而這些服務(wù)器的提供的時(shí)間就是 UTC 時(shí)間。既然定義了 1 秒的確切度量,引入了 TAI 這個(gè)十分精確可靠的時(shí)標(biāo)之后,為什么還要有 UTC 呢?我想應(yīng)該是因?yàn)槿绻蛔非缶_而不顧按天文臺(tái)實(shí)際測(cè)量的時(shí)間的話,時(shí)間一久 TAI 和 UT1 兩個(gè)時(shí)間標(biāo)準(zhǔn)的間隔就會(huì)越來越大,比如,按以往經(jīng)驗(yàn)太陽在正頭頂?shù)臅r(shí)候應(yīng)該是 12 點(diǎn),而實(shí)際上 TAI 告訴我們時(shí)間已經(jīng) 13 點(diǎn)。所以就協(xié)調(diào)出這么一個(gè) UTC 時(shí)間,使得其在 TAI 的基礎(chǔ)上,通過必要時(shí)加入閏秒來保證與 UT1 的間隔不超過 0.9 秒,同時(shí)又可以保持與 TAI 的聯(lián)系:TAI - UTC = N * SI 秒。這個(gè) N 就是實(shí)行「加閏秒」這個(gè)機(jī)制以后在 UTC 上所加的閏秒的總數(shù)(根據(jù)中文維基百科最后一次閏秒是 2016 年的最后一刻,那是迄今為止加的第 37 秒,所以這里的 N 就是 37)。加閏秒是什么意思呢,跟閏二月一樣,閏二月有 29 天,加入了閏秒的那一分鐘會(huì)有 61 秒,即如果你的電腦和手機(jī)的系統(tǒng)支持閏秒的話,那天在 23:59:59 之后會(huì)有 23:59:60,然后才是第二天的 00:00:00。

對(duì)應(yīng)引用:

總而言之, UTC 就是一個(gè)現(xiàn)今被人們廣泛參考并使用的時(shí)標(biāo)。

下面簡(jiǎn)單介紹 Date 對(duì)象。Date 類型是 JavaScript 里內(nèi)置的引用類型,使用自 UTC 1970 年 1 月 1 日子夜開始經(jīng)過的毫秒數(shù)來保存日期。首先,它是一個(gè)函數(shù),作為構(gòu)造,接受的參數(shù)類型有:

  • String:可以表示日期的字符串,其實(shí)此時(shí)是在后臺(tái)先調(diào)用 Date.parse(String) 后再將趕回的結(jié)果傳給 new Date()
  • int|String[, int|String[, int|String...]]:表示年、月、日、時(shí)、分、秒的數(shù)字或?qū)?yīng)字符串,此時(shí)是在后臺(tái)對(duì)傳入的參數(shù)調(diào)用 Date.UTC() 然后再將結(jié)果傳給 new Date()
  • Date:也可以直接傳入一個(gè) Date 類型的對(duì)象,相當(dāng)于重新 copy 一個(gè)相同的 Date 對(duì)象
    作為普通函數(shù),不管傳入什么值,統(tǒng)一返回本地當(dāng)前時(shí)間對(duì)應(yīng)的字符串,即 new Date().toString()。

下面介紹下 Date.parse() 和 Date.UTC():

  • Date.parse():parse() 接受一個(gè)表示日期的字符串參數(shù),然后嘗試根據(jù)這個(gè)字符串返回相應(yīng)日期的毫秒數(shù),字符串的格式官方?jīng)]有統(tǒng)一規(guī)定,通常因地區(qū)而異。這里需要注意的是,雖然 new Date() 返回的對(duì)象的 toString() 方法返回的是表示當(dāng)?shù)貢r(shí)間的字符串,但是 Date.parse() 返回的毫秒數(shù)是時(shí)區(qū) 0 對(duì)應(yīng)時(shí)間的毫秒數(shù),比如在 GMT+8 時(shí)區(qū)調(diào)用 Date.parse('1970-1-1') 按理返回的是 0,但是實(shí)際上返回的是時(shí)區(qū) 0 對(duì)應(yīng)時(shí)間的毫秒數(shù) -28800000(剛好等于 8 * 3600 * 1000)。此外另一個(gè)需要注意的是,iPhone safari 瀏覽器上在 Date.parse() 上 調(diào)用類似 '2012-12-12 12:12' 這樣格式的參數(shù)時(shí),會(huì)返回 NaN,所以對(duì)應(yīng)的 new Date() 也會(huì)返回 'Invalid Date' 的信息。此時(shí)可以通過把字符串解析成一個(gè)數(shù)組 arr,然后調(diào)用 new Date(...arr) 就可以
  • Date.UTC():UTC() 接受多個(gè)表示年、月、日、時(shí)、分、秒的數(shù)字或?qū)?yīng)字符串,其中第一個(gè)表示年份的參數(shù)是必須的,后面的默認(rèn)為 0,且月份的范圍為 0 到 11;與 parse() 不同的是,它返回的是本地時(shí)間所對(duì)應(yīng)的毫秒數(shù),就是說 Date.UTC(1970, 0, 1) 返回的就是 0。

Date 類型重寫了 Object 對(duì)象,toString、toLocaleString、valueOf 三個(gè)方法,前兩個(gè)方法都返回當(dāng)前日期對(duì)應(yīng)的字符串,但前者是帶 GMT 信息的,后者返回帶上下午信息的本地時(shí)間; valueOf 方法返回的是日期對(duì)應(yīng)的毫秒數(shù)。因此對(duì)于兩個(gè) Date 對(duì)象可以直接進(jìn)行「比較」操作和「減法」操作,但是不能直接調(diào)用「加法」操作,因?yàn)椤讣臃ā沟牟僮鲾?shù)是 Object 類型時(shí),是先調(diào)用其 toString() 方法,此時(shí)的結(jié)果會(huì)是兩個(gè)字符串相加。需要 (+date2) + (+date2) 才可以。

getUTCHours() 和 getHours(),帶 UTC 和不帶 UTC 的區(qū)別是前者趕回的是轉(zhuǎn)換成時(shí)區(qū) 0 的日期,后者是本地日期,建議在做運(yùn)算時(shí)統(tǒng)一使用時(shí)區(qū) 0 的日期,待需要展示的之后再轉(zhuǎn)換成本地日期。

對(duì)應(yīng)操作日期的庫,moment 和 dayjs,moment 很強(qiáng)大,比如各種各樣的格式化、日期 add 和 substract等,但是有時(shí)候可能太重了,這時(shí)候可以用 dayjs 這個(gè)稍輕量一點(diǎn)的庫,api 一樣,功能基本不差。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 如果不注意,大概很多人認(rèn)為“閏月”與“閏年”是一個(gè)意思,其實(shí)不是,雖說只是一字之差,所包含的意思卻相差很遠(yuǎn)。 “閏...
    雨落未驚風(fēng)閱讀 13,603評(píng)論 1 2
  • Date類型 Date類型使用自UTC(Coordinated Universal Time,國(guó)際協(xié)調(diào)時(shí)間) 19...
    胖胖冰閱讀 814評(píng)論 0 0
  • 概述 Date對(duì)象是JavaScript提供的日期和時(shí)間的操作接口。它可以表示的時(shí)間范圍是,1970年1月1日00...
    許先生__閱讀 582評(píng)論 0 1
  • 1. 概念 Date對(duì)象是JavaScript提供的日期和時(shí)間的操作接口。它可以表示的時(shí)間范圍是,1970年1月1...
    plainnany閱讀 2,128評(píng)論 0 1
  • 歲數(shù)輕的人聽?wèi)颍袝r(shí)候很尷尬。 聽?wèi)蛞^癮,最好是聽老戲,老戲又得是老角兒唱的才好,可是老角兒在世的已經(jīng)不多了,也...
    拐子流星錘閱讀 647評(píng)論 0 5

友情鏈接更多精彩內(nèi)容