【譯】Javascript中的日期對象

原文:css-tricks.com/everything-…
做者:Zell Liew
譯者:前端小白javascript

日期在JavaScript中很奇怪。當咱們須要處理日期和時間的時候,它會讓咱們很是焦慮,以致於咱們須要藉助於date -fnsMoment這樣的庫 可是咱們並不老是須要使用庫。若是你知道哪些地方須要注意,日期對象其實很簡單。在本文中,我將帶您瞭解關於Date對象的全部內容。 首先,讓咱們討論下時區css

時區

世界上有上百個時區,在JavaScript中,咱們只關心兩個時區:本地時間和協調世界時(UTC)前端

  • 本地時間是指您的計算機所在的時區。
  • UTC實際上就是格林威治標準時間(GMT)。

默認狀況下,JavaScript中的幾乎每一個日期方法(除了一個)都以本地時間顯示日期/時間。只有當指定UTC時纔會獲得UTC。在這個前提下,咱們來討論建立日期對象java

創造一個日期對象

你可使用new date建立一個日期。有四種方式使用new Date():git

  • 日期格式的字符串
  • 日期類型的參數
  • 時間戳
  • 空參數

日期字符串形式

在構造方法中,經過將日期格式的字符串傳遞給new date來建立一個日期。編程

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

咱們更傾向於這種方式,這更貼近咱們日常生活的書寫方式 若是寫成21-03-1988,咱們能夠推斷出正確的日期1988年3月21日,可是在js裏面,21-03-1988是無效的日期,你會獲得Invalid Date數組

new Date('21-03-1988') returns Invalid Date.

在世界的不一樣地方,對日期字符串的解釋是不一樣的。例如11-06-2019不是2019年6月11日就是2019年11月6日。可是你不能肯定我指的是哪個,除非你知道我使用的哪一種日期系統。瀏覽器

在JavaScript中,若是想使用日期字符串,須要使用一種全世界都接受的格式。其中一種格式是 ISO 8601 Extended formatbash

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

這些值表明:編程語言

  • YYYY:四位數字的年
  • MM:兩數字的月(一月是01,12月是12)
  • DD:兩位數字的日期(0-31)
  • -:日期分隔符
  • T: 指定開始時間
  • HH: 24小時制時間表示(0-23)
  • mm: 分鐘 (0 to 59)
  • ss: 秒 (0 to 59)
  • sss: 毫秒 (0 to 999)
  • :: 時間分隔符
  • Z: 若是制定了Z,日期就會被表示爲UTC. 若是 Z 沒有指定,則爲當地時間. (僅只適用於提供時間的狀況)

若是要建立日期,小時、分鐘、秒和毫秒都是可選的。因此,若是你想爲2019年6月11日設定一個日期,你能夠這樣寫:

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

這裏要特別注意。使用日期字符串建立日期有一個很大的問題。若是console.log這個日期,就會發現問題。

若是你住在格林威治標準時間以後的地區,你會獲得一個日期是6月10日。

new Date('2019-06-11') produces 10th June if you're in a place behind GMT.

若是你住在格林尼治時間以前,你會獲得一個日期是6月11

new Date('2019-06-11')produces 11th June if you're in a place after GMT.

這是由於日期字符串這種方式有一個特殊的行爲:若是你建立一個日期(不指定時間),您將獲得一個UTC中的日期集。

在上面的場景中,當new Date('2019-06-11')時,實際上建立的日期是2019年6月11日,UTC時間上午12點。這就是爲何住在格林尼治標準時間以後的地區的人獲得的是6月10日而不是6月11日

若是但願使用日期字符串的形式在本地時間建立日期,則須要包含時間。當你包括時間,你至少須要HHmm(或谷歌Chrome返回一個無效的日期)。

new Date('2019-06-11T00:00')
複製代碼
Date created in Local Time vsl. Date created in UTC.

本地時間和UTC類型的日期字符串這二者可能會產生錯誤,並且難以被發現。因此,我建議你不要使用日期字符串建立日期。(順便說一下,MDN也警告不要使用日期字符串方法,由於瀏覽器可能以不一樣的方式解析日期字符串)

MDN recommends against creating date with date strings.
若是要建立日期,請使用參數或時間戳。

使用參數建立日期

你能夠傳遞給new Date()七種類型的參數來建立一個日期/時間

  1. Year: 四位數的年.
  2. Month: 月份 (0-11). 月份從0開始,若是省略,默認是0.
  3. Day: 天 (1-31). 若是省略,默認是1.
  4. Hour: 小時 (0-23). 若是省略,默認是0.
  5. Minutes: 分鐘 (0-59). 若是省略,默認是0.
  6. Seconds: 秒 (0-59). 若是省略,默認是0.
  7. Milliseconds: 毫秒 (0-999). 若是省略,默認是0。
// 11th June 2019, 5:23:59am, Local Time
new Date(2019, 5, 11, 5, 23, 59)
複製代碼

許多開發人員(包括我本身)都避免使用arguments方法,由於它看起來很複雜。其實很簡單。

試着從左到右閱讀數字,依次遞減爲:年、月、日、小時、分鐘、秒和毫秒。

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
複製代碼

Date中最讓人費解的地方是月份的值是從0開始的,例如,January === 0, February === 1, March === 2等等。

咱們不知道爲何會這樣,但確實javascript就是這麼設計的。因此與其爭論不如接受。 一旦你接受了這個事實,日期變得很是容易使用。

這裏還有一些例子可讓你熟悉下:

// 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之間混淆。 若是您須要UTC,請以這種方式建立UTC日期:

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

用時間戳建立日期

在JavaScript中,時間戳是自1970年1月1日以來通過的毫秒數(1970年1月1日也稱爲Unix紀元時間)。 根據個人經驗,您不多使用時間戳來建立日期。 您只能使用時間戳來比較不一樣的日期(稍後會詳細介紹)。

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

空參數建立日期

若是您建立一個沒有任何參數的日期,您將獲得一個設置爲當前時間的日期(在本地時間中)。

當前時間
你能夠從圖像中看出,當我寫這篇文章時,它是5月25日上午11點10分在新加坡。

建立日期方式總結

  1. 你可使用 new Date()建立日期.
  2. 有四種可行的語法:
    1. 日期字符串
    2. 參數形式
    3. 時間戳
    4. 空參數
  3. 不要使用日期字符串形式.
  4. 最好使用參數形式.
  5. 謹記月份是從0開始索引的.

接下來,讓咱們討論將日期轉換爲可讀字符串。

格式化日期

大多數編程語言都提供了格式化工具來建立所需的任何日期格式。例如,在PHP中,可使用date(「d M Y」)將日期格式化爲2019年1月23日。

但在javascript中沒有這種簡便的方式

原生Date對象提供了7種格式化方法。這七個方法中的每個都爲您提供了一個特定的值(它們很是無用)。

const date = new Date(2019, 0, 23, 17, 23, 42)
複製代碼
  1. toString --> Wed Jan 23 2019 17:23:42 GMT+0800 (Singapore Standard Time)
  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 這種格式,你須要使用Date對象提供的方法。 要獲取日期,可使用如下四種方法:

  1. getFullYear: 根據當地時間獲取四位數表示的年
  2. getMonth: 根據當地時間獲月 (0-11).
  3. getDate: 根據當地時間獲取日期,一個月中的第多少天 (1-31).
  4. getDay: 根據當地時間獲取一週中的第多少天 (0-6),一週是指 Sunday (0) 到 Saturday (6).

因此,爲了建立Thu, 23 January 2019這種格式,咱們能夠這樣來作:

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

可是,Thu,January 就有點難度了 要得到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'
}
複製代碼

因爲Month是零索引的,因此咱們可使用數組而不是對象。它會產生相同的結果。

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

如今你能夠這麼作:

  1. 使用 getMonth 獲得月份對應的索引.
  2. 根據索引從 months 獲取對應的月份
const monthIndex = d.getMonth()
const monthName = months[monthIndex]
console.log(monthName) // January
複製代碼

相同方法能夠獲取到Thu,建立一個包含一週七天的數組。

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

而後:

  1. 使用 getDay 獲得 dayIndex
  2. 根據 dayIndex 獲得 dayName
const dayIndex = d.getDay()
const dayName = days[dayIndex] // Thu
複製代碼

而後,將建立的全部變量組合起來以得到格式化的字符串。

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

的確,這樣作很麻煩,可是一旦你掌握了,就簡單了

若是須要建立自定義格式的時間,可使用如下方法(所有是根據當地時間):

  1. getHours: 小時 (0-23).
  2. getMinutes: 分鐘 (0-59).
  3. getSeconds: 秒 (0-59).
  4. 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
複製代碼

若是想檢查兩個日期是否在同一天,能夠比較它們的getFullYeargetMonthgetDate值。

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: Set 4-digit year in Local Time.
  2. setMonth: Set month of the year in Local Time.
  3. setDate: Set day of the month in Local Time.
  4. setHours: Set hours in Local Time.
  5. setMinutes: Set minutes in Local Time.
  6. setSeconds: Set seconds in Local Time.
  7. setMilliseconds: Set milliseconds in Local Time.

例如,若是想將日期設置爲一個月中的15號,可使用setDate(15)

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

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

月份也是同樣,記住,月份是從0開始的

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

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

注意:上面的setter方法會改變原始日期對象。 在實際中,咱們不該該改變原對象(瞭解更多 )咱們應該在新的日期對象上執行這些操做。

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
複製代碼

從某個日期的基礎上增長或者減小值

經過在另外一個日期添加/減去delta,個人意思是:您但願從另外一個日期得到X的日期。 它能夠是X年,X月,X天等。

要得到delta,您須要知道當前日期的值。 您可使用如下方法獲取它:

  1. getFullYear: Gets 4-digit year according to local time
  2. getMonth: Gets month of the year (0-11) according to local time.
  3. getDate: Gets day of the month (1-31) according to local time.
  4. getHours: Gets hours (0-23) according to local time.
  5. getMinutes: Gets minutes (0-59) according to local time.
  6. getSeconds: Gets seconds (0-59) according to local time.
  7. getMilliseconds: Gets milliseconds (0-999) according to local time.

添加/減去delta有兩種通用方法。 第一種方法在Stack Overflow上更受歡迎。 它簡潔,但更難掌握。 第二種方法更冗長,但更容易理解。

咱們假設今天是2019年3月28日,你想要一個三天之後的日期

第一種方式

// Assumes today is 28 March 2019
const today = new Date(2019, 2, 28)
複製代碼

首先,咱們建立一個新的Date對象(這樣咱們就不會更改原始日期)

const finalDate = new Date(today)
複製代碼

接下來,咱們須要知道咱們想要改變的值。 因爲咱們想改變的天數,因此咱們能夠經過getDate得到天。

const currentDate = today.getDate()
複製代碼

想得到三天之後的日期,咱們將使用將delta(3)添加到當前日期

finalDate.setDate(currentDate + 3)
複製代碼

完整代碼:

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

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

第一種方式

咱們使用getFullYeargetMonthgetDate和其餘getter方法,直到獲得咱們想要更改的類型。而後,使用 new Date 來建立日期。

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
複製代碼

日期自動糾錯

若是爲Date提供一個超出其可接受範圍的值,JavaScript將自動從新計算日期。

假如咱們將日期設置爲33rd March 2019,這是個無效的日期,JavaScript 會自動將 33rd March 調整到 2nd April.

// 33rd March => 2nd April
new Date(2019, 2, 33)
複製代碼
33rd March gets converted to 2nd April automatically.

這意味着在建立一個增量時,您不須要擔憂計算分鐘、小時、天、月等。JavaScript自動爲您處理它。

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

以上就是你須要瞭解的關於JavaScript的原生日期對象的知識

相關文章
相關標籤/搜索