Date
Baseline 廣泛可用 *
JavaScript Date 物件以平臺無關的格式表示時間中的某個特定瞬間。Date 物件封裝了一個整數,該整數表示自 1970 年 1 月 1 日午夜(UTC)(即**“紀元”**)以來經過的毫秒數。
描述
紀元、時間戳和無效日期
JavaScript 日期從根本上講是自紀元以來經過的毫秒數,紀元定義為 1970 年 1 月 1 日午夜(UTC)(等同於 UNIX 紀元)。這個時間戳**與時區無關**,唯一地定義了歷史上的一個瞬間。
注意: 儘管 Date 物件核心的時間值是 UTC 時間,但獲取日期和時間或其組成部分的基本方法都在本地(即主機系統)時區和偏移量中執行。
Date 物件可表示的最大時間戳略小於最大安全整數(Number.MAX_SAFE_INTEGER,即 9,007,199,254,740,991)。Date 物件相對於紀元最大可表示 ±8,640,000,000,000,000 毫秒,即 ±100,000,000(一億)天。這範圍從公元前 271821 年 4 月 20 日到公元 275760 年 9 月 13 日。任何試圖表示此範圍之外時間的嘗試都會導致 Date 物件持有 NaN 的時間戳值,即“無效日期”。
console.log(new Date(8.64e15).toString()); // "Sat Sep 13 275760 00:00:00 GMT+0000 (Coordinated Universal Time)"
console.log(new Date(8.64e15 + 1).toString()); // "Invalid Date"
有各種方法允許你與日期中儲存的時間戳進行互動
- 你可以使用
getTime()和setTime()方法直接與時間戳值進行互動。 valueOf()和[Symbol.toPrimitive]()(當傳入"number"時)方法——它們在數字強制轉換中會自動呼叫——返回時間戳,使得Date物件在數字上下文中使用時表現得像它們的時間戳。- 所有靜態方法(
Date.now()、Date.parse()和Date.UTC())都返回時間戳而不是Date物件。 Date()建構函式可以只用一個時間戳作為引數進行呼叫。
日期組成部分和時區
日期在內部表示為單個數字,即**時間戳**。與它互動時,時間戳需要被解釋為結構化的日期和時間表示。解釋時間戳始終有兩種方式:作為本地時間或作為協調世界時(UTC),這是由世界時間標準定義的全球標準時間。本地時區不儲存在日期物件中,而是由主機環境(使用者裝置)決定。
注意: UTC 不應與 格林威治平均時間(GMT)混淆,因為它們並非總是相等——這在連結的維基百科頁面中有更詳細的解釋。
例如,時間戳 0 表示歷史上的一個獨特瞬間,但它可以有兩種解釋方式
- 作為 UTC 時間,它是 1970 年 1 月 1 日午夜(UTC),
- 作為紐約(UTC-5)的本地時間,它是 1969 年 12 月 31 日 19:00:00。
getTimezoneOffset() 方法返回 UTC 與本地時間之間的分鐘差。請注意,時區偏移量不僅取決於當前時區,還取決於 Date 物件所表示的時間,因為存在夏令時和歷史變化。本質上,時區偏移量是 Date 物件所表示的時間和主機環境所在位置與 UTC 時間的偏移量。
Date 方法分為兩組:一組透過將時間戳解釋為本地時間來獲取和設定各種日期元件,而另一組則使用 UTC。
Date() 建構函式可以傳入兩個或更多引數,這種情況下它們分別被解釋為本地時間中的年、月、日、小時、分鐘、秒和毫秒。Date.UTC() 的工作方式類似,但它將這些元件解釋為 UTC 時間,並且也接受一個表示年份的單個引數。
注意: 包括 Date() 建構函式、Date.UTC() 和已棄用的 getYear()/setYear() 方法在內的一些方法,會將兩位數年份解釋為 20 世紀的年份。例如,new Date(99, 5, 24) 被解釋為 1999 年 6 月 24 日,而不是 99 年 6 月 24 日。有關更多資訊,請參閱兩位數年份的解釋。
當某個片段溢位或欠流其預期範圍時,它通常會“結轉到”或“借用自”更高的片段。例如,如果月份設定為 12(月份從零開始,所以 12 月是 11),它將成為下一年的 1 月。如果日份設定為 0,它將成為上一個月的最後一天。這同樣適用於使用日期時間字串格式指定的日期。
當嘗試將本地時間設定為落在偏移量轉換期間(通常是夏令時)的時間時,確切的時間將使用與 Temporal 的 disambiguation: "compatible" 選項相同的行為推導。也就是說,如果本地時間對應兩個瞬間,則選擇較早的一個;如果本地時間不存在(存在間隙),則按間隙持續時間向前推移。
// Assume America/New_York local time zone
// 2024-03-10 02:30 is within the spring-forward transition and does not exist
// 01:59 (UTC-5) jumps to 03:00 (UTC-4), so 02:30 moves forward by one hour
console.log(new Date(2024, 2, 10, 2, 30).toString());
// Sun Mar 10 2024 03:30:00 GMT-0400 (Eastern Daylight Time)
// 2024-11-03 01:30 is within the fall-back transition and exists twice
// 01:59 (UTC-4) jumps to 01:00 (UTC-5), so the earlier 01:30 (UTC-4) is chosen
console.log(new Date(2024, 10, 3, 1, 30).toString());
// Sun Nov 03 2024 01:30:00 GMT-0400 (Eastern Daylight Time)
日期時間字串格式
將日期格式化為字串有多種方式。JavaScript 規範只指定了一種 universally supported 的格式:日期時間字串格式,它是 ISO 8601 日曆日期擴充套件格式的簡化。格式如下:
YYYY-MM-DDTHH:mm:ss.sssZ
YYYY是年份,四位數字(0000到9999),或帶有+或-後跟六位數字的擴充套件年份。擴充套件年份必須帶符號。明確禁止使用-000000作為有效年份。MM是月份,兩位數字(01到12)。預設為01。DD是月份中的日期,兩位數字(01到31)。預設為01。T是一個字面字元,表示字串中**時間**部分的開始。指定時間部分時,T是必需的。HH是小時,兩位數字(00到23)。作為特例,允許使用24:00:00,並將其解釋為下一天的午夜。預設為00。mm是分鐘,兩位數字(00到59)。預設為00。ss是秒,兩位數字(00到59)。預設為00。sss是毫秒,三位數字(000到999)。預設為000。Z是時區偏移量,可以是字面字元Z(表示 UTC),也可以是+或-後跟HH:mm,即與 UTC 的小時和分鐘偏移量。
各種元件可以省略,因此以下所有格式都是有效的
- 僅日期形式:
YYYY、YYYY-MM、YYYY-MM-DD - 日期時間形式:上述僅日期形式之一,後跟
T,再後跟HH:mm、HH:mm:ss或HH:mm:ss.sss。每種組合都可以後跟時區偏移量。
例如,"2011-10-10"(*僅日期*形式)、"2011-10-10T14:48:00"(*日期時間*形式)或 "2011-10-10T14:48:00.000+09:00"(帶毫秒和時區的*日期時間*形式)都是有效的日期時間字串。
當缺少時區偏移量時,**僅日期形式被解釋為 UTC 時間,而日期時間形式被解釋為本地時間。** 將其解釋為 UTC 時間是由於一個與 ISO 8601 不一致的歷史規範錯誤,但由於網路相容性問題無法更改。請參閱 Broken Parser – A Web Reality Issue。
Date.parse() 和 Date() 建構函式都接受日期時間字串格式的字串作為輸入。此外,當輸入不匹配此格式時,實現允許支援其他日期格式。
toISOString() 方法以日期時間字串格式返回日期的字串表示,時區偏移量始終設定為 Z (UTC)。
注意: 建議您確保輸入符合上述日期時間字串格式,以實現最大相容性,因為不保證支援其他格式。但是,有些格式在所有主要實現中都受支援——例如 RFC 2822 格式——在這種情況下,它們的使用可能是可以接受的。始終進行跨瀏覽器測試以確保您的程式碼在所有目標瀏覽器中都能正常工作。如果需要適應許多不同的格式,可以使用庫來提供幫助。
非標準字串可以按照實現所需的方式進行解析,包括時區——大多數實現預設使用本地時區。實現不要求對超出範圍的日期元件返回無效日期,儘管它們通常會這樣做。字串可能包含在範圍內的日期元件(其範圍如上所述),但實際上並不表示日期(例如,“2 月 30 日”)。在這種情況下,實現的行為不一致。Date.parse() 頁面提供了更多關於這些非標準情況的示例。
其他日期格式化方式
toISOString()返回1970-01-01T00:00:00.000Z格式的字串(上面介紹的日期時間字串格式,它是簡化的 ISO 8601)。toJSON()呼叫toISOString()並返回結果。toString()返回Thu Jan 01 1970 00:00:00 GMT+0000 (Coordinated Universal Time)格式的字串,而toDateString()和toTimeString()分別返回字串的日期和時間部分。[Symbol.toPrimitive]()(當傳入"string"或"default"時)呼叫toString()並返回結果。toUTCString()返回Thu, 01 Jan 1970 00:00:00 GMT格式的字串(通用 RFC 7231)。toLocaleDateString()、toLocaleTimeString()和toLocaleString()使用特定於語言環境的日期和時間格式,通常由IntlAPI 提供。
有關示例,請參閱toString 方法返回值格式部分。
建構函式
Date()-
作為建構函式呼叫時,返回一個新的
Date物件。作為函式呼叫時,返回當前日期和時間的字串表示。
靜態方法
Date.now()-
返回對應當前時間的數值——自 1970 年 1 月 1 日 00:00:00 UTC 以來的毫秒數,忽略閏秒。
Date.parse()-
解析日期的字串表示,並返回自 1970 年 1 月 1 日 00:00:00 UTC 以來的毫秒數,忽略閏秒。
Date.UTC()-
接受與建構函式最長形式相同的引數(即 2 到 7 個),並返回自 1970 年 1 月 1 日 00:00:00 UTC 以來的毫秒數,忽略閏秒。
例項屬性
這些屬性在 Date.prototype 上定義,並由所有 Date 例項共享。
Date.prototype.constructor-
建立例項物件的建構函式。對於
Date例項,初始值是Date建構函式。
例項方法
Date.prototype.getDate()-
根據本地時間返回指定日期的月份中的日期(
1–31)。 Date.prototype.getDay()-
根據本地時間返回指定日期的星期幾(
0–6)。 Date.prototype.getFullYear()-
根據本地時間返回指定日期的年份(四位年份為 4 位數字)。
Date.prototype.getHours()-
根據本地時間返回指定日期中的小時(
0–23)。 Date.prototype.getMilliseconds()-
根據本地時間返回指定日期中的毫秒(
0–999)。 Date.prototype.getMinutes()-
根據本地時間返回指定日期中的分鐘(
0–59)。 Date.prototype.getMonth()-
根據本地時間返回指定日期中的月份(
0–11)。 Date.prototype.getSeconds()-
根據本地時間返回指定日期中的秒數(
0–59)。 Date.prototype.getTime()-
返回指定日期的數值,即自 1970 年 1 月 1 日 00:00:00 UTC 以來的毫秒數。(對於之前的時間返回負值。)
Date.prototype.getTimezoneOffset()-
返回當前語言環境的時區偏移量(以分鐘為單位)。
Date.prototype.getUTCDate()-
根據通用時間返回指定日期中月份的日期(
1–31)。 Date.prototype.getUTCDay()-
根據通用時間返回指定日期中星期幾(
0–6)。 Date.prototype.getUTCFullYear()-
根據通用時間返回指定日期中的年份(四位年份為 4 位數字)。
Date.prototype.getUTCHours()-
根據通用時間返回指定日期中的小時(
0–23)。 Date.prototype.getUTCMilliseconds()-
根據通用時間返回指定日期中的毫秒(
0–999)。 Date.prototype.getUTCMinutes()-
根據通用時間返回指定日期中的分鐘(
0–59)。 Date.prototype.getUTCMonth()-
根據通用時間返回指定日期中的月份(
0–11)。 Date.prototype.getUTCSeconds()-
根據通用時間返回指定日期中的秒數(
0–59)。 Date.prototype.getYear()已棄用-
根據本地時間返回指定日期中的年份(通常為 2-3 位數字)。請改用
getFullYear()。 Date.prototype.setDate()-
根據本地時間設定指定日期的月份中的日期。
Date.prototype.setFullYear()-
根據本地時間設定指定日期的完整年份(例如,四位年份為 4 位數字)。
Date.prototype.setHours()-
根據本地時間設定指定日期的小時。
Date.prototype.setMilliseconds()-
根據本地時間設定指定日期的毫秒。
Date.prototype.setMinutes()-
根據本地時間設定指定日期的分鐘。
Date.prototype.setMonth()-
根據本地時間設定指定日期的月份。
Date.prototype.setSeconds()-
根據本地時間設定指定日期的秒數。
Date.prototype.setTime()-
將
Date物件設定為自 1970 年 1 月 1 日 00:00:00 UTC 以來的毫秒數所表示的時間。對於之前的時間使用負數。 Date.prototype.setUTCDate()-
根據通用時間設定指定日期的月份中的日期。
Date.prototype.setUTCFullYear()-
根據通用時間設定指定日期的完整年份(例如,四位年份為 4 位數字)。
Date.prototype.setUTCHours()-
根據通用時間設定指定日期的小時。
Date.prototype.setUTCMilliseconds()-
根據通用時間設定指定日期的毫秒。
Date.prototype.setUTCMinutes()-
根據通用時間設定指定日期的分鐘。
Date.prototype.setUTCMonth()-
根據通用時間設定指定日期的月份。
Date.prototype.setUTCSeconds()-
根據通用時間設定指定日期的秒數。
Date.prototype.setYear()已棄用-
根據本地時間設定指定日期的年份(通常為 2-3 位數字)。請改用
setFullYear()。 Date.prototype.toDateString()-
以人類可讀的字串形式返回
Date的“日期”部分,例如'Thu Apr 12 2018'。 Date.prototype.toISOString()-
將日期轉換為遵循 ISO 8601 擴充套件格式的字串。
Date.prototype.toJSON()-
使用
toISOString()返回表示Date的字串。旨在被JSON.stringify()隱式呼叫。 Date.prototype.toLocaleDateString()-
根據系統設定,返回此日期的日期部分,以語言環境敏感的字串表示。
Date.prototype.toLocaleString()-
返回此日期的語言環境敏感表示的字串。覆蓋
Object.prototype.toLocaleString()方法。 Date.prototype.toLocaleTimeString()-
根據系統設定,返回此日期的時間部分,以語言環境敏感的字串表示。
Date.prototype.toString()-
返回表示指定
Date物件的字串。覆蓋Object.prototype.toString()方法。 Date.prototype.toTemporalInstant()實驗性-
返回一個新的
Temporal.Instant物件,其epochMilliseconds值與此日期的時間戳相同。 Date.prototype.toTimeString()-
以人類可讀的字串形式返回
Date的“時間”部分。 Date.prototype.toUTCString()-
使用 UTC 時區將日期轉換為字串。
Date.prototype.valueOf()-
返回
Date物件的原始值。覆蓋Object.prototype.valueOf()方法。 Date.prototype[Symbol.toPrimitive]()-
將此
Date物件轉換為原始值。
示例
建立 Date 物件的幾種方式
以下示例展示了建立 JavaScript 日期的幾種方式
注意: 從字串建立日期存在許多行為不一致之處。有關使用不同格式的注意事項,請參閱日期時間字串格式。
const today = new Date();
const birthday = new Date("December 17, 1995 03:24:00"); // DISCOURAGED: may not work in all runtimes
const birthday2 = new Date("1995-12-17T03:24:00"); // This is standardized and will work reliably
const birthday3 = new Date(1995, 11, 17); // the month is 0-indexed
const birthday4 = new Date(1995, 11, 17, 3, 24, 0);
const birthday5 = new Date(628021800000); // passing epoch timestamp
toString 方法返回值的格式
const date = new Date("2020-05-12T23:50:21.817Z");
date.toString(); // Tue May 12 2020 18:50:21 GMT-0500 (Central Daylight Time)
date.toDateString(); // Tue May 12 2020
date.toTimeString(); // 18:50:21 GMT-0500 (Central Daylight Time)
date[Symbol.toPrimitive]("string"); // Tue May 12 2020 18:50:21 GMT-0500 (Central Daylight Time)
date.toISOString(); // 2020-05-12T23:50:21.817Z
date.toJSON(); // 2020-05-12T23:50:21.817Z
date.toUTCString(); // Tue, 12 May 2020 23:50:21 GMT
date.toLocaleString(); // 5/12/2020, 6:50:21 PM
date.toLocaleDateString(); // 5/12/2020
date.toLocaleTimeString(); // 6:50:21 PM
獲取日期、月份和年份或時間
const date = new Date("2000-01-17T16:45:30");
const [month, day, year] = [
date.getMonth(),
date.getDate(),
date.getFullYear(),
];
// [0, 17, 2000] as month are 0-indexed
const [hour, minutes, seconds] = [
date.getHours(),
date.getMinutes(),
date.getSeconds(),
];
// [16, 45, 30]
兩位數年份的解釋
new Date() 在處理兩位數年份值時表現出遺留的、不一致的不良行為;具體來說,當 new Date() 呼叫給定兩位數年份值時,該年份值不會被視為字面年份並按原樣使用,而是被解釋為相對偏移量——在某些情況下是相對於 1900 年的偏移量,但在其他情況下是相對於 2000 年的偏移量。
let date = new Date(98, 1); // Sun Feb 01 1998 00:00:00 GMT+0000 (GMT)
date = new Date(22, 1); // Wed Feb 01 1922 00:00:00 GMT+0000 (GMT)
date = new Date("2/1/22"); // Tue Feb 01 2022 00:00:00 GMT+0000 (GMT)
// Legacy method; always interprets two-digit year values as relative to 1900
date.setYear(98);
date.toString(); // Sun Feb 01 1998 00:00:00 GMT+0000 (GMT)
date.setYear(22);
date.toString(); // Wed Feb 01 1922 00:00:00 GMT+0000 (GMT)
因此,要建立和獲取 0 到 99 年之間的日期,請改用首選的 setFullYear() 和 getFullYear() 方法:。
// Preferred method; never interprets any value as being a relative offset,
// but instead uses the year value as-is
date.setFullYear(98);
date.getFullYear(); // 98 (not 1998)
date.setFullYear(22);
date.getFullYear(); // 22 (not 1922, not 2022)
計算經過的時間
以下示例展示瞭如何確定兩個 JavaScript 日期之間經過的毫秒數。
由於天(因夏令時變更)、月和年的長度不同,以小時、分鐘和秒以外的單位表示經過時間需要解決許多問題,在嘗試之前應進行徹底研究。
// Using Date objects
const start = Date.now();
// The event to time goes here:
doSomethingForALongTime();
const end = Date.now();
const elapsed = end - start; // elapsed time in milliseconds
// Using built-in methods
const start = new Date();
// The event to time goes here:
doSomethingForALongTime();
const end = new Date();
const elapsed = end.getTime() - start.getTime(); // elapsed time in milliseconds
// To test a function and get back its return
function printElapsedTime(testFn) {
const startTime = Date.now();
const result = testFn();
const endTime = Date.now();
console.log(`Elapsed time: ${String(endTime - startTime)} milliseconds`);
return result;
}
const yourFunctionReturn = printElapsedTime(yourFunction);
注意: 在支援 效能 API 高解析度時間功能的瀏覽器中,Performance.now() 可以提供比 Date.now() 更可靠和精確的經過時間測量。
獲取自 ECMAScript 紀元以來的秒數
const seconds = Math.floor(Date.now() / 1000);
在這種情況下,重要的是隻返回一個整數——所以簡單的除法不行。同樣重要的是隻返回實際經過的秒數。(這就是為什麼這段程式碼使用 Math.floor(),而**不是** Math.round()。)
規範
| 規範 |
|---|
| ECMAScript® 2026 語言規範 # sec-date-objects |
瀏覽器相容性
載入中…