[譯] JAVASCRIPT 日期權威指南

在 JavaScript 中使用日期是很複雜的。請試着學習全部特性並學會如何使用它。javascript

引言

在工做中使用日期是很是複雜的。不管開發人員的技術如何,都會感覺到至關痛苦。前端

JavaScript 經過一個強大的 Date 內建對象來提供處理日期的功能。java

這篇文章不會討論 Moment.js 這個我認爲是處理日期的最好的庫,你應該在絕大多數場景下用它來處理日期。android

Date 對象

一個 Date 對象實例描述一個單一的時間點。ios

儘管其被命名爲 Date,但其也操縱着 具體的時間(譯者注:意爲其也能夠描述時分秒)。git

初始化一個 Date 對象

咱們經過如下方式初始化一個 Date 對象:github

new Date()
複製代碼

這將會創造一個指向當前時刻的 Date 對象。後端

從內部來看,Date 對象是表示距離 1970 年 1 月 1 日(UTC)所過去的毫秒數。這一天(1970 年 1 月 1 日)是很是重要的,由於就計算機而言,這是一切開始的地方。瀏覽器

你可能比較熟悉 UNIX 時間戳:它表示距離衆人皆知的那天(1970 年 1 月 1 日)所過去的秒數。bash

要點:UNIX 時間戳的結果是「秒」,JavaScript 的 Date 對象的結果是「毫秒」。

若是咱們有一個 UNIX 時間戳,咱們能夠經過下面的方法類比出一個 JavaScript Date 對象:

const timestamp = 1530826365
new Date(timestamp * 1000)
複製代碼

若是咱們傳值爲 0,咱們將會獲得一個表示 1970年1月1日的 JavaScript Date 對象:

new Date(0)
複製代碼

若是咱們傳值一個字符串而不是數字,那麼Date對象將會調用 parse 去肯定你想傳入的日期。例如:

new Date('2018-07-22')
new Date('2018-07') //July 1st 2018, 00:00:00
new Date('2018') //Jan 1st 2018, 00:00:00
new Date('07/22/2018')
new Date('2018/07/22')
new Date('2018/7/22')
new Date('July 22, 2018')
new Date('July 22, 2018 07:22:13')
new Date('2018-07-22 07:22:13')
new Date('2018-07-22T07:22:13')
new Date('25 March 2018')
new Date('25 Mar 2018')
new Date('25 March, 2018')
new Date('March 25, 2018')
new Date('March 25 2018')
new Date('March 2018') //Mar 1st 2018, 00:00:00
new Date('2018 March') //Mar 1st 2018, 00:00:00
new Date('2018 MARCH') //Mar 1st 2018, 00:00:00
new Date('2018 march') //Mar 1st 2018, 00:00:00
複製代碼

這個方法很是靈活。你能夠在月份或者日期字段添加或省略前導零。

當心月份/日期的位置,否則你或許會將月份錯當作是日期。

你也可使用 Date.parse 方法:

Date.parse('2018-07-22')
Date.parse('2018-07') //July 1st 2018, 00:00:00(譯者注:此處的結果爲一個時間戳數字,該數字表明 July 1st 2018, 00:00:00 時刻)
Date.parse('2018') //Jan 1st 2018, 00:00:00(譯者注:意思同上)
Date.parse('07/22/2018')
Date.parse('2018/07/22')
Date.parse('2018/7/22')
Date.parse('July 22, 2018')
Date.parse('July 22, 2018 07:22:13')
Date.parse('2018-07-22 07:22:13')
Date.parse('2018-07-22T07:22:13')
複製代碼

Date.parse 方法將會返回一個時間戳(以毫秒計)而不是 Date 對象。

你也能夠經過設置一串有序的表示以一個日期的各個部分的數值來建立一個 Date 對象:年份,月份(從 0 開始),日期,小時,分鐘,秒數和毫秒數:

new Date(2018, 6, 22, 7, 22, 13, 0)
new Date(2018, 6, 22)
複製代碼

這個方法最少須要三個參數,可是大多數 JavaScript 引擎也能夠解析更少參數的狀況:

new Date(2018, 6) //Sun Jul 01 2018 00:00:00 GMT+0200 (Central European Summer Time)
new Date(2018) //Thu Jan 01 1970 01:00:02 GMT+0100 (Central European Standard Time)
複製代碼

在上述所用的狀況下,所生成的 Date 都是與你如今所在的時區相關聯的。這意味着 兩個不一樣的電腦可能將同一個 Date 對象實例解釋成不一樣的值。

JavaScript 在沒有找到任何關於時區的信息時,會把時區設置成 UTC,同時也會自動地(對非當前時區的 Date 對象)進行到當前計算機時區的轉換。

總結一下,你能夠經過四種方式來建立一個 Date 對象:

  • 不傳任何參數 ,這將建立一個指向「當前時刻」的 Date 對象
  • 傳遞 一個數字,該參數將表示建立的 Date 對象距離 1970 年 1 月 1 日 00:00(GMT)所過去的毫秒數
  • 傳遞 一個字符串,該字符串應該是一個描述日期的字符串
  • 傳遞 一串參數,這些參數會分別描述一個 Date 對象的某一部分

時區

當你初始化一個 Date 對象時能夠選擇時區,這樣作的話 Date 對象不會是默認的 UTC 時區,同時也會覆蓋你所在的時區。

你能夠經過添加 +HOURS 的格式,或者經過一個被圓括號包裹的時區名來描述一個時區:

new Date('July 22, 2018 07:22:13 +0700')
new Date('July 22, 2018 07:22:13 (CET)')
複製代碼

若是你使用時區名的方式但在圓括號中定義了一個錯誤的時區名,JavaScript 將會靜默地將時區設置爲默認的 UTC。

若是你使用 +HOURS 的方式但傳入的數字格式是錯誤的,JavaScript 將會拋出一個 「Invalid Date」 的 Error。

Date 轉換及格式化

給定一個 Date 對象,會有許多種能夠生成與該時間相關的字符串的方式。

const date = new Date('July 22, 2018 07:22:13')

date.toString() // "Sun Jul 22 2018 07:22:13 GMT+0200 (Central European Summer Time)"
date.toTimeString() //"07:22:13 GMT+0200 (Central European Summer Time)"
date.toUTCString() //"Sun, 22 Jul 2018 05:22:13 GMT"
date.toDateString() //"Sun Jul 22 2018"
date.toISOString() //"2018-07-22T05:22:13.000Z" (ISO 8601 format)
date.toLocaleString() //"22/07/2018, 07:22:13"
date.toLocaleTimeString()	//"07:22:13"
date.getTime() //1532236933000
date.getTime() //1532236933000
複製代碼

Date 對象的 get(獲取)方法

一個 Date 對象會提供以下方法去查看它的值。這些值會取決於你計算機所處的時區。

const date = new Date('July 22, 2018 07:22:13')

date.getDate() //22
date.getDay() //0(0 表示週日,1 表示週一...)
date.getFullYear() //2018
date.getMonth() //6(從 0 開始計)
date.getHours() //7
date.getMinutes() //22
date.getSeconds() //13
date.getMilliseconds() //0(未標明)(譯者注:此處的意思爲 Date 對象建立時指定毫秒值,JavaScript 默認將毫秒數設置爲 0)
date.getTime() //1532236933000
date.getTimezoneOffset() //-120(將會取決於你在哪和你查看的時間 — 例子中的值表示在 CET 時區的夏天)。返回以分鐘表示的時間差(譯者注:此處涉及到協調世界時及夏令時)
複製代碼

這兒還有一些類似的使用 UTC 時區的方法,它們會使用 UTC 時區而不是你所在的時區。

date.getUTCDate() //22
date.getUTCDay() //0(0 表示週日,1 表示週一...)
date.getUTCFullYear() //2018
date.getUTCMonth() //6(從 0 開始計)
date.getUTCHours() //5(看吧,不是上面的結果「7」)
date.getUTCMinutes() //22
date.getUTCSeconds() //13
date.getUTCMilliseconds() //0(未標明)
複製代碼

修改 Date

一個 Date 對象提供如下修改 Date 值的方法:

const date = new Date('July 22, 2018 07:22:13')

date.setDate(newValue)
date.setDay(newValue)
date.setFullYear(newValue) //note:不要使用 setYear(),它已經被廢棄了
date.setMonth(newValue)
date.setHours(newValue)
date.setMinutes(newValue)
date.setSeconds(newValue)
date.setMilliseconds(newValue)
date.setTime(newValue)
date.setTimezoneOffset(newValue)
複製代碼

setDaysetMonth 的取值範圍從 0 開始,舉個例子,三月的值爲 2。

一個有趣的事實是:這些方法是互相重合的,舉個例子,若是你運行 date.setHours(48),這也會將日期數變大。

很棒的知識點:你能夠對 setHours() 添加超過一個參數來設置分鐘,秒鐘和毫秒:setHours(0, 0, 0, 0) ——這也適用於 setMinutessetSeconds。(譯者注:即 setMinutes 能夠設置分鐘,秒和毫秒,setSeconds 能夠設置秒和毫秒)

和 get(獲取)方法同樣,set(修改)方法也有相同的 UTC 版本:

const date = new Date('July 22, 2018 07:22:13')

date.setUTCDate(newalue)
date.setUTCDay(newValue)
date.setUTCFullYear(newValue)
date.setUTCMonth(newValue)
date.setUTCHours(newValue)
date.setUTCMinutes(newValue)
date.setUTCSeconds(newValue)
date.setUTCMilliseconds(newValue)
複製代碼

獲取正確的時間戳

若是你想得到以毫秒計的時間戳,你可使用以下簡寫:

Date.now()
複製代碼

下面這種方式更加複雜:

new Date().getTime()
複製代碼

JavaScript 費盡心思讓代碼工做正常

請注意。若是你定義的日期天數超過了一個月,這將不會報錯,同時 Date 對象將會指向下一個月:

new Date(2018, 6, 40) //Thu Aug 09 2018 00:00:00 GMT+0200 (Central European Summer Time)
複製代碼

這對月份,小時,分鐘,秒鐘,毫秒一樣有效。

基於你的地點來格式化 Date

全球化的API,在現代化的瀏覽器中被很好地支持(值得注意的例外:UC 瀏覽器),而這容許你去轉化(世界各地的)日期。

這些方法由 Intl 項目公佈,它同時也幫助咱們本地化數字,字符串和貨幣。

咱們對 Intl.DateTimeFormat() 很是有興趣。

這裏說的是如何使用它:

按照電腦所在地區來格式化一個 Date 對象:

// "12/22/2017"
const date = new Date('July 22, 2018 07:22:13')
new Intl.DateTimeFormat().format(date) //"22/07/2018" 是我所在地區的格式
複製代碼

按照不一樣地區來格式化一個 Date 對象:

new Intl.DateTimeFormat('en-US').format(date) //"7/22/2018"
複製代碼

Intl.DateTimeFormat 方法有一個可選的參數能夠去自定義輸出。下面是同時展現小時,分鐘和秒數的方法:

const options = {
  year: 'numeric',
  month: 'numeric',
  day: 'numeric',
  hour: 'numeric',
  minute: 'numeric',
  second: 'numeric'
}

new Intl.DateTimeFormat('en-US', options).format(date) //"7/22/2018, 7:22:13 AM"
new Intl.DateTimeFormat('it-IT', options2).format(date) //"22/7/2018, 07:22:13"
複製代碼

這裏是你可用參數的參考

對比兩個 Date

你能夠經過 Date.getTime() 的值來比較兩個 Date 對象:

const date1 = new Date('July 10, 2018 07:22:13')
const date2 = new Date('July 22, 2018 07:22:13')
const diff = date2.getTime() - date1.getTime() //以毫秒計的差距
複製代碼

一樣的方法,你也能夠去檢查兩個 Date 對象是否相等:

const date1 = new Date('July 10, 2018 07:22:13')
const date2 = new Date('July 10, 2018 07:22:13')
if (date2.getTime() === date1.getTime()) {
  // 它們相等時所執行的代碼
}
複製代碼

謹記,getTime() 方法返回以毫秒計的數字,因此你須要將當日時刻計入對照之中。July 10, 2018 07:22:13 不等於 July 10, 2018。在這種狀況下,你可使用 setHours(0, 0, 0, 0) 來重置當日時刻。

若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。

掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索