沐鳴平台_JavaScript 中的時間處理詳解

本文針對 JavaScript 的內置 Date 對象進行詳細介紹。

1、簡介

JavaScript 提供了內置對象 Date,用於處理時間,它是基於 Unix Time Stamp(Unix 時間戳)的,即從 1970 年 1 月 1 日 0 點 0 時 0 分(UTC)到此刻經過的毫秒數(下文稱該時間為 Unix Zero Time)。

Date.now() // 1593002422045

返回自 Unix Zero Time 以來,到代碼運行時刻的時間戳。

2、創建時間對象

創建一個新的 Date 對象唯一的方法是通過 new 操作符。如果直接調用 Date 函數,返回字符串,而非 Date 對象。

Date 有四種構造函數:

2.1、無參數

調用無參數構造函數,返回代碼執行時刻的時間。

let now = new Date()  // Wed Jun 24 2020 20:54:21 GMT+0800 (中國標準時間)

2.2、Unix 時間戳作為參數值

提供 Unix 時間戳作為參數值,該值表示自 “1970 年 1 月 1 日 00:00:00” 以來的毫秒數。

// 當前時間
let now = new Date() 
// Wed Jun 24 2020 20:59:39 GMT+0800 (中國標準時間)

// 兩小時以後的時間
let later = new Date(now.getTime() + 2 * 60 * 60 * 1000) 
// Wed Jun 24 2020 22:59:39 GMT+0800 (中國標準時間)

2.3、日期字符串

該字符串必須符合 IETF-compliant RFC 2822 timestamps 或 version of ISO8601 格式。

// 提供 ISO8601 格式的日期字符串
new Date('2020-06-24T16:06:26.860Z') 
// Thu Jun 25 2020 00:06:26 GMT+0800 (中國標準時間)

// 提供 RFC 2822 格式的日期字符串
new Date('24 Jun 2020 16:06:26 GMT') 
// Thu Jun 25 2020 00:06:26 GMT+0800 (中國標準時間)
new Date('Wed, 24 Jun 2020 16:06:26 GMT') 
// Thu Jun 25 2020 00:06:26 GMT+0800 (中國標準時間)

注意:

強烈建議不要使用這種指定日期字符串的方式構造 Date 對象,因為瀏覽器差異,會導致解析不一致。同時,也不建議使用 Date.parse() 方法解析時間。

考慮自己寫一個方法解析時間字符串,或使用一些時間處理框架。

2.4、分別提供日期成員

語法:Date(year, monthIndex, ?day, ?hours, ?minutes, ?seconds, ?milliseconds)

year – 如果填 0-99 ,會映射為 1900 到 1999年,其他值表示實際年份,也可以小於 1970。

monthIndex – 表示月份的索引,從 0 開始表示第 1 月,默認為 0。

day – 表示一個月中的第幾天,從 1 開始,默認為 1。

hours – 表示一天中的小時數(24 小時制),默認為 0。

minutes – 表示分鐘,默認為 0。

seconds – 表示秒,默認為 0。

milliseconds – 表示毫秒,默認為 0。

最少提供 2 個參數:year,monthIndex,最多 7 個。

你可能期望僅提供一個參數 year,實際上這會被當成“時間戳構造方式”來處理。

new Date(2000)
// Thu Jan 01 1970 08:00:02 GMT+0800 (中國標準時間)

下面我們來創建一個 Date 對象,希望表示 21 世紀第一天。

// 1月份以 0 開始的
new Date(2000, 0, 1)
// Sat Jan 01 2000 00:00:00 GMT+0800 (中國標準時間)

實際上,以上時間並非 UTC 時間,傳入的參數默認表示的是本地時間。

如果想要轉換為 UTC 時間,可以調用 Date.UTC() 得到時間戳后,再傳給 Date 構造函數。

注意:默認創建的對象是表示本地時間的,而非 UTC 時間。因此,以上代表的時間只是北京時間到了世紀之初,而非世界時已經進入了新世紀,因為我們在東八區,比 UTC 時間晚 8 個小時。

let millis = Date.UTC(2000, 0, 1)
// 這才真正的21世紀第一天
new Date(millis)
// Sat Jan 01 2000 08:00:00 GMT+0800 (中國標準時間)

如果參數超出合理範圍,會自動進位。

new Date(2000, 0, 1)
// Sat Jan 01 2000 00:00:00 GMT+0800 (中國標準時間)

// 月份超出了 11,多了 1 個月,進位到下一年的 1 月。
new Date(2000, 12, 1)
// Mon Jan 01 2001 00:00:00 GMT+0800 (中國標準時間)

// 日期超出了 1 月 的最大值 31,多了 1 天,進位為 2 月 1 日
new Date(2000,0, 32)
// Tue Feb 01 2000 00:00:00 GMT+0800 (中國標準時間)

// 日期超出的天數可以跨多個月
new Date(2000, 0, 60)
// Tue Feb 29 2000 00:00:00 GMT+0800 (中國標準時間)

// 碰到跨 2 月時,還可以自動處理閏月的天數問題
// 2000 年 2 月是 29 天
new Date(2000, 0, 61)
// Wed Mar 01 2000 00:00:00 GMT+0800 (中國標準時間)

// 其他 hour, minutes, minute, milliseconds 類似,不再贅述

3、方法

3.1、各種 toString 方法

let now = new Date(2000, 0)

// 以下輸出為本地時間表示的字符串
now.toString() // Sat Jan 01 2000 00:00:00 GMT+0800 (中國標準時間)
now.toDateString() // "Sat Jan 01 2000"
now.toTimeString() // "00:00:00 GMT+0800 (中國標準時間)"
now.toLocalString() // "2000/1/1 上午12:00:00"
now.toLocaleDateString() // "2000/1/1"
now.toLocaleTimeString() // "上午12:00:00"

// 以下輸出為 UTC 時間表示的字符串
now.toISOString() // "1999-12-31T16:00:00.000Z"
now.toUTCString() // "Fri, 31 Dec 1999 16:00:00 GMT"
now.toGMTString() // "Fri, 31 Dec 1999 16:00:00 GMT"
now.tojsON() // "1999-12-31T16:00:00.000Z"

上述示例可以看出:tojsON 方法和 toISOString 的輸出格式是一樣的;toUTCString 和 toGMTString 的輸出格式是一樣的。

3.2、獲取時間各部分的方法

getter 方法:

getFullYear,getMonth,getDate,getHours,getMinutes,getSeconds,getMilliseconds,getUTCFullYear,getUTCMonth,getUTCDate,getUTCHours,getUTCMinutes,getUTCSeconds,getUTCMilliseconds

setter 方法:

setFullYear,setMonth,setDate,setHours,setMinutes,setSeconds,setMilliseconds,setUTCFullYear,setUTCMonth,setUTCDate,setUTCHours,setUTCMinutes,setUTCSeconds,setUTCMilliseconds

let now = new Date(2000, 0) // Sat Jan 01 2000 00:00:00 GMT+0800 (中國標準時間)
// 輸入為 ISO8601 格式,方便查看
now.toISOString() // "1999-12-31T16:00:00.000Z"

// 以下方法基於本地時間輸出
now.getFullYear() // 2000
now.getMonth() // 0, 注意:這裏以 0 開始的 monthIndex,因此 1 月輸出為 0
now.getDate() // 1
now.getHours() // 0
now.getMinutes() // 0
now.getSeconds() // 0
now.getMilliseconds() // 0
// 以上 getter 方法對應的 setter 方法的示例說明略

// 以下方法基於 UTC 的時間
now.getUTCFullYear() // 1999
now.getUTCMonth() // 11,注意:這裏以 0 開始的 monthIndex,因此 12 月輸出為 11
now.getUTCDate() // 31
now.getUTCHours() // 16
now.getUTCMinutes() // 0
now.getUTCSeconds() // 0
now.getUTCMilliseconds() // 0
// 以上 getter 方法對應的 setter 方法的示例說明略

注意

getYear 已廢棄,請使用 getFullYear,雖然有些瀏覽器還支持,但不建議再使用它,因為很明顯它有“千年蟲問題”(作者也堪稱程序界老油條啊,95 年發布 JavaScript,他就沒想到 2000 年只有幾年就要到了嗎?還是明知道就是不想去改?)

3.3、其他方法

使用 getTimezoneOffset 可以獲得本地時區和 UTC 之間的偏移分鐘數。

new Date().getTimezoneOffset() // 480

返回值 480分鐘,即 8 小時,因為本地時間為北京時間,處於東八區。

valueOf() 返回時間戳, getTime(),Date.now() 也返回時間戳。

let timestamp = Date.now() // 1593013216800
let now = new Date(timestamp)
now.valueOf() // 1593013216800
now.getTime() // 1593013216800

4、總結

強烈建議不要使用 new Date(dateString) 或 Date.parse(dateString) 方法解析日期,因為各瀏覽器的實現差異可能會造成解析失敗。

getYear, setYear 已經廢棄,雖然瀏覽器還支持它,但不建議使用。

調用那些不帶 UTC 的方法名,一般都是基於本地時間的;如果想基於 UTC 時間,使用那些帶 UTC 的方法。

以“分別指定時間各部分”的方式構造 Date 實例時,默認是基於本地時間的,如果要想基於 UTC 時間,可以將各時間參數先傳入 Date.UTC() 方法,通過該方法返回的時間戳,再傳給 new Date(timestamp) 創建。

5、參考

MDN: JavaScript 標準內置對象 Date

moment.js 時間處理庫

作者: codedog996

出處:https://www.cnblogs.com/ktgu/p/13806520.html

站長推薦

1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

鏈接: http://www.fly63.com/article/detial/9724