原文:css-tricks.com/everything-…
做者:Zell Liew
譯者:前端小白javascript
日期在JavaScript中很奇怪。當咱們須要處理日期和時間的時候,它會讓咱們很是焦慮,以致於咱們須要藉助於date -fns
和Moment
這樣的庫 可是咱們並不老是須要使用庫。若是你知道哪些地方須要注意,日期對象其實很簡單。在本文中,我將帶您瞭解關於Date
對象的全部內容。 首先,讓咱們討論下時區css
世界上有上百個時區,在JavaScript中,咱們只關心兩個時區:本地時間和協調世界時(UTC)前端
默認狀況下,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日
。
若是但願使用日期字符串的形式在本地時間建立日期,則須要包含時間。當你包括時間,你至少須要HH
和mm
(或谷歌Chrome返回一個無效的日期)。
new Date('2019-06-11T00:00')
複製代碼
本地時間和UTC類型的日期字符串這二者可能會產生錯誤,並且難以被發現。因此,我建議你不要使用日期字符串建立日期。(順便說一下,MDN也警告不要使用日期字符串方法,由於瀏覽器可能以不一樣的方式解析日期字符串)
你能夠傳遞給new Date()
七種類型的參數來建立一個日期/時間
Year
: 四位數的年.Month
: 月份 (0-11). 月份從0開始,若是省略,默認是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)
複製代碼
許多開發人員(包括我本身)都避免使用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)
複製代碼
若是您建立一個沒有任何參數的日期,您將獲得一個設置爲當前時間的日期(在本地時間中)。
new Date()
建立日期.接下來,讓咱們討論將日期轉換爲可讀字符串。
大多數編程語言都提供了格式化工具來建立所需的任何日期格式。例如,在PHP中,可使用date(「d M Y」)
將日期格式化爲2019年1月23日。
但在javascript中沒有這種簡便的方式
原生Date
對象提供了7種格式化方法。這七個方法中的每個都爲您提供了一個特定的值(它們很是無用)。
const date = new Date(2019, 0, 23, 17, 23, 42)
複製代碼
toString
--> Wed Jan 23 2019 17:23:42 GMT+0800 (Singapore Standard Time)toDateString
--> Wed Jan 23 2019toLocaleString
--> 23/01/2019, 17:23:42toLocaleDateString
--> 23/01/2019toGMTString
--> Wed, 23 Jan 2019 09:23:42 GMTtoUTCString
--> Wed, 23 Jan 2019 09:23:42 GMTtoISOString
--> 2019-01-23T09:23:42.079Z若是您須要自定義格式,則須要本身建立。
假設你想要的是Thu, 23 January 2019
這種格式,你須要使用Date對象提供的方法。 要獲取日期,可使用如下四種方法:
getFullYear
: 根據當地時間獲取四位數表示的年getMonth
: 根據當地時間獲月 (0-11).getDate
: 根據當地時間獲取日期,一個月中的第多少天 (1-31).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'
]
複製代碼
如今你能夠這麼作:
getMonth
獲得月份對應的索引.months
獲取對應的月份const monthIndex = d.getMonth()
const monthName = months[monthIndex]
console.log(monthName) // January
複製代碼
相同方法能夠獲取到Thu
,建立一個包含一週七天的數組。
const days = [
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat'
]
複製代碼
而後:
getDay
獲得 dayIndex
dayIndex
獲得 dayName
const dayIndex = d.getDay()
const dayName = days[dayIndex] // 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
複製代碼
還有最後一個問題,咱們須要討論
有兩種可能的狀況,您但願從一個日期獲取另外一個日期。
你可使用下列方法,爲某個日期設置時間/日期值,方法都是比較語義化的:
setFullYear
: Set 4-digit year in Local Time.setMonth
: Set month of the year in Local Time.setDate
: Set day of the month in Local Time.setHours
: Set hours in Local Time.setMinutes
: Set minutes in Local Time.setSeconds
: Set seconds in Local Time.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,您須要知道當前日期的值。 您可使用如下方法獲取它:
getFullYear
: Gets 4-digit year according to local timegetMonth
: Gets month of the year (0-11) according to local time.getDate
: Gets day of the month (1-31) according to local time.getHours
: Gets hours (0-23) according to local time.getMinutes
: Gets minutes (0-59) according to local time.getSeconds
: Gets seconds (0-59) according to local time.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
複製代碼
第一種方式
咱們使用getFullYear
、getMonth
、getDate
和其餘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)
複製代碼
這意味着在建立一個增量時,您不須要擔憂計算分鐘、小時、天、月等。JavaScript自動爲您處理它。
// 33rd March => 2nd April
new Date(2019, 2, 30 + 3)
複製代碼
以上就是你須要瞭解的關於JavaScript的原生日期對象的知識