Date 物件
JavaScript 沒有日期資料型別,但它有內建物件 Date 物件,可以用來處理日期與時間。Date 物件是以世界標準時間(UTC) 1970 年 1 月 1 日為零點,範圍為前後各 1 億天(+-100,000,000),單位為毫秒(ms)。
Date 物件只能由 new Date()
作為建構器來產生,不帶參數使用將會建立當前時間的 Date 物件:
|
|
Date 實體求值時,與其他物件預設呼叫 valueOf
方法不同,它預設會呼叫 toString
方法,因此求值時會回傳完整日期時間格式的字串:
|
|
若是作為普通函式直接呼叫 Date
,會回傳完整日期時間格式的字串,而非 Date 物件,無法使用 Date 物件方法:
|
|
CodePen Demo:JavaScript 日期時間 - Date 物件
基礎概念
1. 時間標準
- GTM(Greenwich Mean Time)格林威治標準時間,已經被原子鐘報時的世界協調時間(UTC)所取代。
- UTC(Coordinated Universal Time)世界協調時間,是最主要的世界時間標準。
- TAI(International Atomic Time)國際原子時,是根據以下秒的定義的一種國際參照時標。
由於地球自轉是稍微不規則的(緩慢減速),因此格林威治標準時間已經被原子鐘報時的世界協調時間所取代。但 GMT 和 UTC 在一般使用的情況下(不需要非常精確的情況)並沒有差異,所以通常將 GMT 和 UTC 視為等同,舉例來說:台灣時區可以標示為 GMT+8 或 UTC+8 。
2. 時區
時區 是地球上的區域使用同一個時間定義。
- 時差,世界各國位於地球不同位置上,因此不同國家,特別是東西跨度大的國家日出、日落時間必定有所偏差。這些偏差就是所謂的時差。
- 偏移(offset),指的是某地區與 GTM/UTC 偏移的時間,例如
+08:00
表示該地區的時間比 GTM/UTC 快了 8 小時。 - 理論時區,指的是以被 15 整除的經線為中心,向東西兩側延伸 7.5°,即每 15° 劃分一個時區。
- 法定時區,指的是為了避開國界線,有的時區的形狀並不規則,而且比較大的國家以國家內部行政分界線為時區界線,這是實際時區。
- 夏令時間(Daylight Saving Time, DST),指的是一種在夏季將時間調快一小時的做法。
建立 Date 物件
new Date()
語法基本為四種形式的參數:
- 空值(不帶參數)
- 毫秒
- 日期時間字串
- 時間單位
|
|
1. 不帶參數
new Date()
不帶參數,表示當前日期時間的 Date 物件。
|
|
2. 毫秒
new Date(milliseconds)
,milliseconds
表示從 1970-01-01 00:00:00 UTC+0
開始所經過的毫秒數。
|
|
經過一百天:
|
|
3. 日期時間字串
new Date(datestring)
,datestring
表示一個日期或時間格式的字串,該參數會通過 Date.parse
算法解析字串。
日期時間格式字串定義(ISO8601):
YYYY-MM-DDTHH:mm:ss.sssZ
- 日期
YYYY-MM-DD
:年-月-日
- 字串
T
:是一個分隔符號 - 時間
HH:mm:ss.sss
:小時:分鐘:秒.毫秒
- 時區:UTC+8 使用
+08:00
表示,若時區為 UTC+0 可使用Z
表示。
|
|
:::warning
若輸入非標準日期字串,會根據各家瀏覽器的實現方式,而有不同的結果。詳細可以參考 MDN 說明。
:::
:::warning
另外要注意,Date 物件在建立時,會將日期時間轉成本地時區(作業系統設定的時區)輸出,並不支持指定時區輸出。
:::
4. 時間單位
new Date(year, month, [date, hours, minutes, seconds, ms])
- 必要參數:年、月
- 年(必須是四位數)
- 月 (
0
~11
)
- 選擇性的參數:日、時、分、秒、毫秒
- 日(預設為
1
) - 時、分、秒、毫秒(預設為
0
)
- 日(預設為
預設的時區為本地時區(作業系統設定的時區):
|
|
如果超出正確範圍內的數字會自動轉換成對應時間:
|
|
獲取 & 設定
1. 獲取
從 Date 物件取的相對應的時間數值(number
),可以使用 Date 提供的方法:
getFullYear()
:年份(四位數)getMonth()
:月份從0
到11
getDate()
:當月的日期,從1
到31
getHours()
:時getMinutes()
:分getSeconds()
:秒getMilliseconds()
:毫秒getDay()
:獲取一週中的第幾天,0
到6
(起始為星期日)
以上所有的方法回傳的訊息都是基於當地時區的。
|
|
如果要獲取標準時間,則可以使用對應的 UTC
版本,例如 getUTCFullYear()
、getUTCMonth()
等等。
2. 設定
以下方法可以設置時間訊息:
setFullYear(year [, month, date])
setMonth(month [, date])
setDate(date)
setHours(hour [, min, sec, ms])
setMinutes(min [, sec, ms])
setSeconds(sec [, ms])
setMilliseconds(ms)
以上方法會回傳改變後的時間戳,另外,也都有對應的 UTC
版本,例如 setUTCHours()
。
3. 結合使用
兩者方法結合使用,可以得到相對時間:
|
|
時間戳(Timestamp)
時間戳(Timestamp)指的是從 1970-1-1 00:00:00 UTC+0
開始的毫秒數。
1. 靜態方法
Date 的靜態方法:
Date.now()
:回傳當前時間的數值時間戳。Date.parse()
:解析日期或時間格式的字串,回傳該時間的數值時間戳(由於瀏覽器之間的不同與差異,不建議使用)。Date.UTC()
:需要傳入與建構器相同的參數(即年月日等等參數),回傳該時間的數值時間戳。
|
|
|
|
:::warning
輸入的參數會視為世界標準時間,而非本地時間,與建構器不同。
:::
2. 時間戳轉換
Date 物件轉時間戳的方法:
getTime()
:回傳日期的時間戳。
|
|
如果將 Date 物件轉成數值(呼叫 valueOf()
),相當於 getTime()
方法。
1. Unix 時間戳
一般來說,後端給的時間會是以秒為單位的 Unix 時間戳,但 JavaScript 的時間戳單位為毫秒。
如果我們有一個 Unix 時間戳,可以透過乘 1000 取得 Date 物件:
|
|
反之,如果要將時間戳轉 Unix 時間戳 就是除 1000:
|
|
運算
如果對 Date 物件進行減法運算,會自動轉換成對應的毫秒數:
|
|
若是加法運算則是字串連接:
|
|
因此我們可以先將時間轉換成成毫秒,再進行運算:
|
|
減法運算可以直接相減,但加法運算必須使用 getTime()
轉毫秒再運算:
|
|
轉換格式
1. 基本格式字串
toString()
:回傳完整的日期時間字串。toUTCString()
:回傳 UTC 格式字串。toISOString()
:回傳 ISO8601 格式字串。toJSON()
:與toISOString()
回傳結果相同。toDateString()
:回傳日期字串,不含小時、分和秒。toTimeString()
:回傳時間字串,不含年月日。
|
|
2. 本地格式字串
本地格式字串,會因不同語言而有不同的輸出格式:
toLocaleString()
:完整的日期時間字串。toLocaleDateString()
:日期,不含小時、分和秒。toLocaleTimeString()
:時間,不含年月日。
|
|
3. 本地格式參數
上述三個本地格式字串方法都有兩個可選的參數:
|
|
locales
:字串,指定所用語言。值可參考 地區設定 - 列表,中文為"zh"
、台灣為"zh-TW"
。options
:選項物件,設定格式化規則。
詳細用法可以參考 Natively Format JavaScript Dates and Times 文章。
第三方函式庫
1. Moment.js
Moment.js 是處理 JavaScript 日期時間熱門函式庫。
不過,官方已宣佈停止開發,進入維護狀態,官方公告。
官方總結了兩大問題:
- Moment 物件是可變物件;
- 體積過大。
替代方案:
2. Day.js
Day.js 函式庫是 Moment.js 輕量化替代方案,API 設計與 Moment.js 相同。
Day.js 沒有對 Date.prototype
做任何修改,而是對 Date 物件做了一層封裝。Day.js 物件是不可變的,所有的 API 操作都將回傳一個全新的實體,避免修改到原始資料。
Day.js
1. 解析
呼叫 dayjs()
,建立 Day.js 物件
|
|
2. 獲取 & 設置
不傳參數為 getter、傳參數為 setter,取得的值為本地時間:
|
|
millisecond()
毫秒second()
秒minute()
分鐘hour()
小時(0
~23
超過會進位到天數)date()
日期(1
~31
超過會進位到月份)day()
星期(0
~6
超過會進位到下週)month()
月份(0
~11
超過會進位到年份)year()
年份
單位字串 | 縮寫 | 說明 |
---|---|---|
date |
D |
月份裡的日期 |
day |
d |
星期幾(0 ~ 6 ) |
month |
M |
月份(0 ~ 11 ) |
year |
y |
年份 |
hour |
h |
小時 |
minute |
m |
分鐘 |
second |
s |
秒 |
millisecond |
ms |
毫秒 |
|
|
3. 操作
Day.js 支持像這樣的鏈式呼叫一些方法來操作 Day.js 物件。
加減操作:
單位字串 | 縮寫 | 說明 |
---|---|---|
day |
d |
星期幾(0 ~ 6 ) |
week |
w |
周 |
month |
M |
月份(0 ~ 11 ) |
year |
y |
年份 |
hour |
h |
小時 |
minute |
m |
分鐘 |
second |
s |
秒 |
millisecond |
ms |
毫秒 |
|
|
時間開頭、末尾操作:
單位字串 | 縮寫 | 說明 |
---|---|---|
year |
y |
今年一月一日零時 |
month |
M |
本月一日零時 |
week |
w |
當周第一日零時 |
day |
d |
當日零時 |
date |
d |
當日零時 |
hour |
h |
當前時間零分零秒零毫秒 |
minute |
m |
當前時間零秒零毫秒 |
second |
s |
當前時間零毫秒 |
末尾則相反。
|
|
4. 顯示
呈現 Day.js 物件的方法。
格式化 format()
:
佔位符號 | 輸出 | 說明 |
---|---|---|
YY |
18 | 兩位數的年份 |
YYYY |
2018 | 四位數的年份 |
M |
1-12 | 月份,從 1 開始 |
MM |
01-12 | 月份,兩位數 |
MMM |
Jan-Dec | 縮寫的月份名稱 |
MMMM |
January-December | 完整的月份名稱 |
D |
1-31 | 月份裡的一天 |
DD |
01-31 | 月份裡的一天,兩位數 |
d |
0-6 | 一週中的一天,星期天是 0 |
dd |
Su-Sa | 最簡寫的星期幾 |
ddd |
Sun-Sat | 簡寫的星期幾 |
dddd |
Sunday-Saturday | 星期幾 |
H |
0-23 | 小時 |
HH |
00-23 | 小時,兩位數 |
h |
1-12 | 小時, 12 小時制 |
hh |
01-12 | 小時, 12 小時制,兩位數 |
m |
0-59 | 分鐘 |
mm |
00-59 | 分鐘,兩位數 |
s |
0-59 | 秒 |
ss |
00-59 | 秒 兩位數 |
SSS |
000-999 | 毫秒 三位數 |
Z |
+05:00 | UTC 的偏移量,±HH:mm |
ZZ |
+0500 | UTC 的偏移量,±HHmm |
A |
AM PM | |
a |
am pm |
|
|
時間差 diff()
:
|
|
預設單位是毫秒,第二個參數可更改單位(預設取整數),第三參數可以取得浮點數:
|
|
取得實體時間戳:
|
|
取得實體 Unix 時間戳:
|
|
取得當月份天數:
|
|
取得原生 Date 物件:
|
|
取得日期時間字串:
|
|
5. 查詢
Day.js 物件的查詢方法。
比較:
- 是否在之前
isBefore()
- 是否在之後
isAfter()
- 使否相同
isSame()
回傳 Boolean,第二參數可選,指定比較單位。
|
|
dayjs.isDayjs()
可以判斷是否為 Day.js 物件:
|
|
6. 國際化 i18n
Day.js 完美支持國際化,但需要加載,支持語言列表可以參考 locale
資料夾。
詳細可以參考 官方文件 說明。