關於JavaScript中的Date你須要知道的一切

Date 對象在 JavaScript 中是很是奇怪的,以致於咱們在處理時間和日期時,須要使用第三方庫 date-fnsMoment 來處理。javascript

可是並非任什麼時候候都須要引入這些庫,若是你足夠了解日期對象的話它其實很簡單,在這篇文章中我將帶你瞭解全部關於日期對象的信息。css

首先,先從時區開始。java

時區

世界上有幾百個時區,但在 JavaScript 中,你只須要了解兩個就行:當地時間和世界協調時(UTC)。git

當地時間:指你的計算機所在的時區 世界協調時:是最主要的世界時間標準,是最接近格林威治標準時間(GMT),默認狀況下,Date 對象建立的都是當地時間,只有在指定 UTC 時它纔會建立世界協調時。github

有了這個,就能夠來談論日期建立了。數組

建立日期

你能夠經過 new Date() 來建立日期,它有四種使用方式:瀏覽器

  1. 日期字符串
  2. 日期參數
  3. 時間戳
  4. 無參數

1.日期字符串

new Date 傳遞一個日期字符串來建立工具

new Date('1988-03-21');
複製代碼

在建立日期時,咱們傾向於這種日期字符串方法。由於這很天然符合咱們的默認習慣。若是你寫成 21-03-1988,在 JavaScript 中它是無效的。ui

緣由是由於:spa

在世界上不一樣的地方,對日期字符有不一樣的理解,例如: 11-06-2019 你能夠認爲是 11th June, 2019 你也能夠認爲是 6th November 2019。若是不告訴你時間系統,根本沒法得知到底該是哪一個。

JavaScript 中,若是你想使用日期字符串,就必須使用一種全世界通用的格式,其中的一種格式就是 ISO 8601 Extended format

// ISO 8601 Extended format
`YYYY-MM-DDTHH:mm:ss:sssZ`
複製代碼

其中:

  • YYYY:4 位數的年份
  • MM:2 位數的月份(01-12)
  • DD:2 位數的日期(0-31)
  • -:日期分隔符
  • T:指示時間的開始
  • HH: 小時 (0 to 23)
  • mm: 分鐘 (0 to 59)
  • ss: 秒數 (0 to 59)
  • sss: 毫秒 (0 to 999)
  • : :時間分隔符
  • Z:時區,有 Z 採用 UTC 時區,沒有則是當地時區(僅限有時間的狀況)

注意:原文中的 DD:2 位數的日期(0-31)有誤,經求證 DD 應爲 (01 to 31)可查看Date Time String Format

其中,小時、分鐘、秒和毫秒是可選的。所以,若是想建立一個日期 2019年6月11日,你能夠這麼作:

new Date('2019-06-11')
複製代碼

請注意,若是你用 console.log 打印出這個日期,會發現存在一個很大的問題。

若是此時你在 GMT 時區「以後」的地區,獲得的是:6月10日。

若是此時你是在 GMT 時區「以前」的地區,你獲得的是:6月11日。

出現這種現象的緣由是:當使用日期字符串時它會有一個特殊的行爲:若是建立一個不指定時間的日期,它會以 UTC(世界協調時) 爲時區。

因此若是你想建立本地時間,你須要加上 HHmm

new Date('2019-06-11T00:00')
複製代碼

經過上面可以看出使用日期字符串時,可能會由於本地時間和世界協調時出現何難捕捉的錯誤。

因此推薦你不要使用日期字符串來建立日期

順便說一下,MDN 也警告不要使用日期字符串方法,由於瀏覽器可能會以不一樣的方式解析日期字符串。

若是要建立日期,請使用參數或時間戳。

2.參數

你最多能夠傳遞 7 個參數來建立日期。

  • Year: 4 爲數年份
  • Month: 月份 (0-11),默認值爲 0
  • Day:天(1-31),默認值爲 1
  • Hour:小時(0-23),默認值爲 0
  • Minutes:分鐘 (0-59),默認值爲 0
  • Seconds:秒數(0-59),默認值爲 0
  • Milliseconds: 毫秒數 (0-999),默認值爲 0
// 11th June 2019, 5:23:59am, Local Time
new Date(2019, 5, 11, 5, 23, 59)
複製代碼

由於它看起來複雜,致使不少開發人員都不常用此方法來建立日期,但事實上卻很簡單。

它的參數從左到右分別爲:年,月,日,時,分,秒,毫秒。就是這麼簡單。

new Date(2017, 3, 22, 5, 23, 50)

// This date can be easily read if you follow the left-right formula.
// Year: 2017,
// Month: April (because month is zero-indexed)
// Date: 22
// Hours: 05
// Minutes: 23
// Seconds: 50
複製代碼

惟一最大的問題就是月份的索引是從 0 開始的。如1月=== 0,2月=== 1,3月=== 2等等。

咱們不知道爲何月份的索引是從 0 開始的,但確實如此,與其爭論爲何不從 1 開始,不如試着去接收,一旦你接收了這個事實,它就變得容易多了。

經過幾個例子熟悉一下:

// 21st March 1988, 12am, Local Time.
new Date(1988, 2, 21)

// 25th December 2019, 8am, Local Time.
new Date(2019, 11, 25, 8)

// 6th November 2023, 2:20am, Local Time
new Date(2023, 10, 6, 2, 20)

// 11th June 2019, 5:23:59am, Local Time
new Date(2019, 5, 11, 5, 23, 59)
複製代碼

你會發現使用參數建立的時間都是本地時間,這也是它的好處之一,不會像日期字符串那樣會產生不一樣的結果。

若是你想建立UTC(世界協調時)的話,能夠這麼作:

// 11th June 2019, 12am, UTC.
new Date(Date.UTC(2019, 5, 11))
複製代碼

3.時間戳

在 JavaScript 中,時間戳是指自1970年1月1日到如今的毫秒數。據個人經驗不多有人用它來建立日期,由於這個數字每每大的驚人,很很差計算。更多的是使用它來比較兩個日期的大小。

// 11th June 2019, 8am (in my Local Time, Singapore)
new Date(1560211200000)
複製代碼

4.無參數

若是建立不帶有任何的參數,它會返回當前的日期(本地時間)

new Date()
複製代碼

總結

  1. 你能夠經過 new Date()來建立一個日期
  2. 有四種語法能夠建立:
    • 日期字符串
    • 日期參數
    • 時間戳
    • 無參數
  3. 不推薦使用日期字符串,由於它會有不一樣的結果。
  4. 最好的方式是使用參數方式建立,分別對應爲:年,月,日,時,分,秒,毫秒
  5. 記住用參數建立時月份的索引從0開始。

接下來咱們來談談日期格式的轉換。

格式化日期

在其餘語言中會提供格式化工具來建立一個你想要的日期格式,例如:在 PHP 中你能夠用 date("d M Y") 來建立一個像23 Jan 2019這種格式的。

可是在 JavaScript 中格式化日期並無簡單的方法。原生 Date 對象提供了 7 種格式化的方法,可是這 7 種方法返回的都是一個特定的值,並沒有使用價值。

const date = new Date(2019, 0, 23, 17, 23, 42)
複製代碼
  1. toString:返回 Wed Jan 23 2019 17:23:42 GMT+0800 (中國標準時間)
  2. toDateString:Wed Jan 23 2019
  3. toLocaleString:返回 23/01/2019, 17:23:42
  4. toLocaleDateString:23/01/2019
  5. toGMTString:Wed, 23 Jan 2019 09:23:42 GMT
  6. toUTCString:Wed, 23 Jan 2019 09:23:42 GMT
  7. toISOString:2019-01-23T09:23:42.079Z

若是想要一個自定義的值,此時就須要本身動手實現。

自定義格式

好比你想要一個像 Thu, 23 January 2019這種日期,你須要用到下面四種方法:

  1. getFullYear:根據當地時間獲取4位數的年份
  2. getMonth:根據當地時間獲取一年中的月份(0-11)。月份是零索引的
  3. getDate:根據當地時間獲取一個月中的某一天(1-31)
  4. getDay:根據當地時間獲取一週中的某一天(0-6)。一週中的一天從星期日(0)開始,到星期六(6)結束。

獲取年份和日期很是簡單,直接使用 getFullYeargetDate便可。

const d = new Date(2019, 0, 23)
const year = d.getFullYear() // 2019
const date = d.getDate() // 23
複製代碼

難的是獲取ThuJanuary

想要獲取January能夠建立一個對象,而後讓十二個月的值映射到各自的名稱上。

const months = {
  0: 'January',
  1: 'February',
  2: 'March',
  3: 'April',
  4: 'May',
  5: 'June',
  6: 'July',
  7: 'August',
  8: 'September',
  9: 'October',
  10: 'November',
  11: 'December'
}
複製代碼

由於月份的索引是從 0 開始的,因此咱們可使用數組來代替對象,其結果是同樣的。

const months = [
  'January',
  'February',
  'March',
  'April',
  'May',
  'June',
  'July',
  'August',
  'September',
  'October',
  'November',
  'December'
]
複製代碼

獲取January,你須要:

  1. 使用 getMonth獲取到索引
  2. 從 months 獲取到名稱。
const monthIndex = d.getMonth()
const monthName = months[monthIndex]
console.log(monthName) // January
複製代碼

可合併爲

const monthName = months(d.getMonth())
console.log(monthName) // January
複製代碼

一樣的你能夠用相同的方式來獲取到 Thu

const days = [
  'Sun',
  'Mon',
  'Tue',
  'Wed',
  'Thu',
  'Fri',
  'Sat'
]
複製代碼

而後:

  1. 使用 getDay 獲取索引
  2. 從 days 獲取到名稱。
const dayName = days[d.getDay()] // Thu
複製代碼

至此,咱們把上面的字符所有鏈接起來,就能夠獲得想要的結果。

const formatted = `${dayName}, ${date} ${monthName} ${year}`
console.log(formatted) // Thu, 23 January 2019
複製代碼

若是想建立自定義時間格式,能夠用下面幾個方法:

  • getHours:根據當地時間獲取小時數(0-23)。
  • getMinutes: 根據當地時間獲取分鐘數(0-59)。
  • getSeconds: 根據當地時間獲取秒(0-59)。
  • getMilliseconds: 根據本地時間獲取毫秒(0-999)。

接下來,咱們來繼續談日期的比較。

日期比較

若是想比較兩個日期的大小,可直接使用比較符 >、<、>=、<= 。

const earlier = new Date(2019, 0, 26)
const later = new Date(2019, 0, 27)

console.log(earlier < later) // true
複製代碼

但若是你想比較兩個日期是否相等,此時使用 == 或 === 卻無能爲力了。

const a = new Date(2019, 0, 26)
const b = new Date(2019, 0, 26)

console.log(a == b) // false
console.log(a === b) // false
複製代碼

想要比較兩個日期是否相等,可使用 getTime 來獲取時間戳來進行比較。

const isSameTime = (a, b) => {
  return a.getTime() === b.getTime()
}

const a = new Date(2019, 0, 26)
const b = new Date(2019, 0, 26)
console.log(isSameTime(a, b)) // true
複製代碼

若是想檢查兩個日期是否在同一天,能夠檢查它們的 getFullYear、getMonth 和 getDate 的值。

const isSameDay = (a, b) => {
  return a.getFullYear() === b.getFullYear() &&
    a.getMonth() === b.getMonth() &&
    a.getDate()=== b.getDate()
}

const a = new Date(2019, 0, 26, 10) // 26 Jan 2019, 10am
const b = new Date(2019, 0, 26, 12) // 26 Jan 2019, 12pm
console.log(isSameDay(a, b)) // true
複製代碼

最後咱們在談一件事

計算日期

有兩種可能的狀況:

  1. 設置特定日期/時間
  2. 增長/減小日期

設定特定日期

你能夠用如下方法設定日期:

  1. setFullYear:設置年份
  2. setMonth:設置月份
  3. setDate:設置天
  4. setHours:設置時
  5. setMinutes:設置分鐘
  6. setSeconds:設置秒數
  7. setMilliseconds:設置毫秒數

例如能夠將日期設置爲 15號:

const d = new Date(2019, 0, 10)
d.setDate(15)

console.log(d) // 15 January 2019
複製代碼

若是想將月份設置爲 6 月,能夠用 setMonth (月的索引要從 0 開始)

const d = new Date(2019, 0, 10)
d.setMonth(5)

console.log(d) // 10 June 2019
複製代碼

注意:上面的方法咱們都修改了原始的對象,實際上咱們不該該這麼改變對象爲何在這裏,應該建立一個新的對象進行操做。

const d = new Date(2019, 0, 10)
const newDate = new Date(d)
newDate.setMonth(5)

console.log(d) // 10 January 2019
console.log(newDate) // 10 June 2019
複製代碼

增長/減小 日期

想要計算改變後的日期,首先你須要獲取到它們:

  1. getFullYear:根據當地時間獲取4位數的年份
  2. getMonth:根據當地時間獲取一年中的月份(0-11)。月份是零索引的
  3. getDate:根據當地時間獲取一個月中的某一天(1-31)
  4. getHours:根據當地時間獲取小時數(0-23)。
  5. getMinutes: 根據當地時間獲取分鐘數(0-59)。
  6. getSeconds: 根據當地時間獲取秒(0-59)。
  7. getMilliseconds: 根據本地時間獲取毫秒(0-999)。

一般有兩種方法實現日期的增長或減小。第一種:簡介但難理解,第二種,冗長但好理解。

一塊兒來看

假設如今是2019年3月28日,我想要獲得三天後的日期。

第一種方法:

const today = new Date(2019, 2, 28)
const finalDate = new Date(today)
finalDate.setDate(today.getDate() + 3)

console.log(finalDate) // 31 March 2019
複製代碼

第二種方法:

在這裏,咱們使用getFullYear、getMonth、getDate 和其餘getter方法,直到找到想要更改的值的類型。而後咱們用新日期建立最終日期。

const today = new Date(2019, 2, 28)

// Getting required values
const year = today.getFullYear()
const month = today.getMonh()
const day = today.getDate()

// Creating a new Date (with the delta)
const finalDate = new Date(year, month, day + 3)

console.log(finalDate) // 31 March 2019
複製代碼

以上兩種方式都是有效的,你能夠選擇一種去作。

自動修正

若是你提供的日期值超出了其可接受的範圍,JavaScript 會自動從新計算日期。

好比:把日期定在2019年3月33日,在這種狀況下,JavaScript會自動將3月33日調整到4月2日。

// 33rd March => 2nd April
new Date(2019, 2, 33)
複製代碼

這意味着咱們不須要擔憂計算分鐘、小時、天、月等。 JavaScript 會自動幫助咱們處理。

// 33rd March => 2nd April
new Date(2019, 2, 30 + 3)
複製代碼

到這裏,有關於日期對象的全部東西你都已經瞭解啦。

原文:css-tricks.com/everything-…
翻譯:六小登登
更多優質文章:六小登登的博客

我是一名愛寫做的技術人。 關注公衆號:六小登登,後臺回覆「1024」便可免費獲取驚喜福利!後臺回覆「加羣」羣裏天天都會全網蒐羅好文章給你。

相關文章
相關標籤/搜索