Date
)Date
Z
以使日期解析確定本章說明 JavaScript 的 API 以處理日期,也就是 Date
類別。
Date
JavaScript Date
API 使用起來很麻煩。因此,最好依賴函式庫來處理與日期相關的任何事情。熱門的函式庫包括
請參閱部落格文章 “為什麼你不應該使用 Moment.js…” 以了解這些函式庫的優缺點。
此外,TC39 正在為 JavaScript 開發新的日期 API:temporal
。
有兩件事很重要,請記住
樹狀搖晃 可以大幅縮小函式庫的大小。這是一種技術,僅將函式庫的那些匯出部署到某處匯入的網路伺服器。函式比類別更適合樹狀搖晃。
對時區的支援:如 稍後 所說明,Date
不支援時區,這會造成許多陷阱,而且是一個關鍵弱點。請確保你的日期函式庫支援它們。
UTC、Z 和 GMT 都是指定時間的方式,它們很相似,但有細微的差別
UTC(世界協調時間)是所有時區的基礎時間標準。它們是相對於 UTC 指定的。也就是說,沒有任何國家或地區將 UTC 作為其當地時區。
Z(祖魯時區)是一個軍用時區,通常在航空和軍隊中用作 UTC+0 的另一個名稱。
GMT(格林威治標準時間)是一個在一些歐洲和非洲國家使用的時區。它是 UTC 加上零小時,因此與 UTC 時間相同。
來源
日期支援下列時間標準
根據作業的不同,只有部分選項可用。例如,在將日期轉換為字串或擷取時間單位(例如月份中的天數)時,您只能在當地時區和 UTC 之間進行選擇。
在內部,日期會儲存為 UTC。在從當地時區轉換或轉換到當地時區時,必要的偏移會透過日期來決定。在以下範例中,當地時區為歐洲/巴黎
// CEST (Central European Summer Time)
.equal(
assertnew Date('2122-06-29').getTimezoneOffset(), -120);
// CET (Central European Time)
.equal(
assertnew Date('2122-12-29').getTimezoneOffset(), -60);
每當您建立或轉換日期時,您需要留意所使用的時間標準 - 例如:new Date()
使用當地時區,而 .toISOString()
使用 UTC。
> new Date(2077, 0, 27).toISOString()'2077-01-26T23:00:00.000Z'
日期會將 0 解釋為 1 月。在當地時區中,月份中的天數為 27,但在 UTC 中為 26。
記錄每個作業支援的時間標準
在本章節的其餘部分中,每個作業支援的時間標準都會註明。
無法指定時區有兩個缺點
它無法支援多個時區。
它可能導致特定於位置的錯誤。例如,先前的範例會產生不同的結果,具體取決於執行它的位置。為了安全
Z
或時間偏移(有關更多資訊,請參閱下一節)。日期時間格式描述
Date.parse()
new Date()
Date.prototype.toISOString()
以下是 .toISOString()
回傳的日期時間字串範例
'2033-05-28T15:59:59.123Z'
日期時間格式具有下列結構
日期格式:Y=年;M=月;D=日
YYYY-MM-DD
YYYY-MM
YYYY
時間格式:T=分隔符號(字串 'T'
);H=時;m=分;s=秒和毫秒;Z=祖魯時區(字串 'Z'
)
THH:mm:ss.sss
THH:mm:ss.sssZ
THH:mm:ss
THH:mm:ssZ
THH:mm
THH:mmZ
日期時間格式:是日期格式加上時間格式。
YYYY-MM-DDTHH:mm:ss.sssZ
除了 Z
(即 UTC+0)之外,我們也可以指定相對於 UTC 的時間偏移量
THH:mm+HH:mm
(等同)THH:mm-HH:mm
(等同)Z
以確定日期剖析如果在字串尾端加上 Z
,日期剖析不會在不同位置產生不同的結果
沒有 Z
:輸入為 1 月 27 日(在歐洲/巴黎時區),輸出為 1 月 26 日(在 UTC)。
> new Date('2077-01-27T00:00').toISOString()'2077-01-26T23:00:00.000Z'
有 Z
:輸入為 1 月 27 日,輸出為 1 月 27 日。
> new Date('2077-01-27T00:00Z').toISOString()'2077-01-27T00:00:00.000Z'
時間值透過自 1970 年 1 月 1 日 00:00:00 UTC 以來的毫秒數來表示日期。
時間值可用於建立日期
const timeValue = 0;
.equal(
assertnew Date(timeValue).toISOString(),
'1970-01-01T00:00:00.000Z');
將日期轉換為數字會回傳其時間值
> Number(new Date(123))123
排序運算子會將其運算元轉換為數字。因此,您可以使用這些運算子來比較日期
.equal(
assertnew Date('1972-05-03') < new Date('2001-12-23'), true);
// Internally:
.equal(73699200000 < 1009065600000, true); assert
下列方法會建立時間值
Date.now(): number
(UTC)
以時間值回傳目前時間。
Date.parse(dateTimeStr: string): number
(當地時區、UTC、時間偏移量)
剖析 dateTimeStr
並回傳對應的時間值。
Date.UTC(year, month, date?, hours?, minutes?, seconds?, milliseconds?): number
(UTC)
回傳指定 UTC 日期時間的時間值。
Date.prototype.getTime(): number
(UTC)
回傳對應於日期的時間值。
Date.prototype.setTime(timeValue)
(UTC)
將 this
設定為由 timeValue
編碼的日期。
new Date(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, milliseconds?: number)
(當地時區)
兩個參數有陷阱
對於 month
,0 是 1 月,1 是 2 月,依此類推。
如果 0 ≤ year
≤ 99,則加上 1900
> new Date(12, 1, 22, 19, 11).getFullYear()1912
這就是為什麼在本章的其他地方,我們避免使用時間單位 year
,而總是使用 fullYear
。但在這種情況下,我們別無選擇。
範例
> new Date(2077,0,27, 21,49).toISOString() // CET (UTC+1)'2077-01-27T20:49:00.000Z'
請注意,輸入小時 (21) 與輸出小時 (20) 不同。前者是指當地時區,後者是指 UTC。
new Date(dateTimeStr: string)
(當地時區、UTC、時間偏移量)
如果結尾有 Z
,則使用 UTC
> new Date('2077-01-27T00:00Z').toISOString()'2077-01-27T00:00:00.000Z'
如果結尾沒有 Z
或時間偏移量,則使用當地時區
> new Date('2077-01-27T00:00').toISOString() // CET (UTC+1)'2077-01-26T23:00:00.000Z'
如果字串只包含日期,則解釋為 UTC
> new Date('2077-01-27').toISOString()'2077-01-27T00:00:00.000Z'
new Date(timeValue: number)
(UTC)
> new Date(0).toISOString()'1970-01-01T00:00:00.000Z'
new Date()
(UTC)
與 new Date(Date.now())
相同。
日期有時間單位的取得器和設定器,例如
Date.prototype.getFullYear()
Date.prototype.setFullYear(num)
這些取得器和設定器符合下列模式
Date.prototype.get«Unit»()
Date.prototype.set«Unit»(num)
Date.prototype.getUTC«Unit»()
Date.prototype.setUTC«Unit»(num)
以下是支援的時間單位
完整年份
Month
:月份 (0–11)。陷阱:0 是 1 月,依此類推。Date
:月份中的日期 (1–31)Day
(僅取得器):星期中的日期 (0–6,0 是星期日)Hours
:小時 (0–23)Minutes
:分鐘 (0–59)Seconds
:秒 (0–59)Milliseconds
:毫秒 (0–999)還有一個取得器不符合前面提到的模式
Date.prototype.getTimezoneOffset()
傳回當地時區與 UTC 之間的時間差(以分鐘為單位)。例如,對於歐洲/巴黎,它傳回 -120
(CEST,中歐夏令時間)或 -60
(CET,中歐時間)
> new Date('2122-06-29').getTimezoneOffset()-120
> new Date('2122-12-29').getTimezoneOffset()-60
範例日期
const d = new Date(0);
Date.prototype.toTimeString()
(當地時區)
> d.toTimeString()'01:00:00 GMT+0100 (Central European Standard Time)'
Date.prototype.toDateString()
(當地時區)
> d.toDateString()'Thu Jan 01 1970'
Date.prototype.toString()
(當地時區)
> d.toString()'Thu Jan 01 1970 01:00:00 GMT+0100 (Central European Standard Time)'
Date.prototype.toUTCString()
(UTC)
> d.toUTCString()'Thu, 01 Jan 1970 00:00:00 GMT'
Date.prototype.toISOString()
(UTC)
> d.toISOString()'1970-01-01T00:00:00.000Z'
以下三個方法不屬於 ECMAScript,而是屬於 ECMAScript 國際化 API。該 API 有許多用於格式化日期(包括支援時區)的功能,但無法用於剖析日期。
Date.prototype.toLocaleTimeString()
Date.prototype.toLocaleDateString()
Date.prototype.toLocaleString()
練習:建立日期字串
exercises/dates/create_date_string_test.mjs