0%

JS特訓-DAY41-new Date( ) 時間處理

前言

時間是我們在開發系統時最常見的一個功能,來看看該如何使用吧!

Date 語法

建立 Date 物件的時候,只有 4 種用法:

  1. new Date();
  2. new Date(value);
  3. new Date(dateString);
  4. new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]]);

四種用法中,最安全的用法應該就屬第 1 種與第 2 種用法了

以下分別介紹四種用法:

1. new Date( )

要透過 JavaScript 中取得時間就必須使用 Date( ) 的語法,但是需使用 new 建構子來建構日期的方法,將日期的方法宣告儲存至 current 中。

var current = new Date(); //  Wed Aug 12 2020 15:17:24 GMT+0800 (台北標準時間)

var current = Date(); // "Wed Aug 12 2020 15:17:30 GMT+0800 (台北標準時間)"

注意:回傳當下日期時間、時間。如果少了 new 則是會回傳一個當下時間的字串。

2. new Date(value)

需傳入一個整數值,其數值是從 1970-01-01 00:00:00 UTC ( UTC = GMT ) (格林威治標準時間) 到現在的毫秒數 (milliseconds)。

//取得現在時間(毫秒)
const getTime = new Date().getTime(); //1597217133176

new Date(getTime);  // Wed Aug 12 2020 15:25:33 GMT+0800 (台北標準時間)

注意:你在任何瀏覽器開發者工具的 Console 模式下,只要輸出 Date 物件的結果,一律都會使用「本地時間」來顯示該物件的日期時間。

3. new Date(dataString)

一般來說,比較少會直接用 new Date(dateString) 語法來產生日期物件,如果會直接這樣用,通常都是先從 AJAX 或其他地方

讀入一個「日期格式的字串」值,然後才透過 new Date(dateString) 解析字串成為 Date 型別的物件。不過,大部分時候都是

讀入資料後直接輸出字串文字,因此大家不常會遇到解析日期的問題。


若牽涉到日期的相關運算,例如想要計算兩個日期之間的差異天數,或是想知道從特定時間點算起 60 天是幾月幾號,或是想顯

示自訂的日期格式 (民國年),都很有可能會用到日期字串格式解析。

不同的「日期格式字串」在不同瀏覽器上的結果會有所差異 ,因此不建議使用下面這種格式的日期字串 (以 Chrome 做測試)

仔細看你會發現, '2020-08-12''2020/08/12' 回傳顯示的日期時間,兩者相差了 8 個小時,這是因為'2020-08-12'

Chrome 解析為 GMT 格林威治標準時間的日期,我們的「本地時間」是 GMT+8 因此顯示時間會自動加上八小時來顯示。

'2020/08/12'顯示的就是「本地時間」的 2020/08/12,這個小差異你必須特別注意,因為打開你網頁的人不見得位於台灣時

區,因此顯示的日期有可能不是 2020/08/12

new Date('2020-08-12');
// Wed Aug 12 2020 08:00:00 GMT+0800 (台北標準時間)

new Date('2020/08/12');
// Wed Aug 12 2020 00:00:00 GMT+0800 (台北標準時間)

接著我們再加上「時間」部分的字串,看看執行結果

new Date('2020-08-12 15:54:00');
// Wed Aug 12 2020 15:54:00 GMT+0800 (台北標準時間)

new Date('2020/08/12 15:54:00');
// Wed Aug 12 2020 15:54:00 GMT+0800 (台北標準時間)

加上時間之後,兩者不再會相差八小時了,而是通通解譯為「本地時間」。

注意:如果上網的人剛好不在台灣,而你的日期時間代表的是「台灣時區」的時間,這時透過 JavaScript 解析出來的時間,就是錯誤的,因為瀏覽器預設會將這個日期格式的字串解析為「使用者目前瀏覽器的本地時間」,如果你又剛好將日期顯示出來,那麼時間就很有可能出現時差!( 除非你在畫面上很明確地說這個時間就是台灣時區的時間 )

4. new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]])

以下測試幾種日期用法,有發現甚麼不一樣的地方嗎?

new Date();            // Wed Aug 12 2020 16:18:29 GMT+0800 (台北標準時間)
new Date(2020);        // Thu Jan 01 1970 08:00:02 GMT+0800 (台北標準時間)
new Date(2020, 8);     // Tue Sep 01 2020 00:00:00 GMT+0800 (台北標準時間)
new Date(2020, 8, 12); // Sat Sep 12 2020 00:00:00 GMT+0800 (台北標準時間)

我們傳入的第二個參數為「月份」,但是你傳入 8 回傳的卻是 9 月,因為只有這個「月份」的參數是從 0 開始計算的,

沒有人知道為什麼!所以 0 代表「一月」,而 11 代表「十二月」。

如果傳入 12 代表哪個月份?很神奇的,是「十三月」,也就是今年的年份的 12 月自動加上 1 個月,如果你執行的是

new Date(2016, 12, 1); 的話,你得到的日期物件將會是 2017-01-01 這個日期,# WTF!

new Date(2016, 12, 1); // Sun Jan 01 2017 00:00:00 GMT+0800 (台北標準時間)

萬無一失的日期字串格式

ECMAScript Language Specification - ECMA-262 Edition 5.1規格中,有對 Date Time String Format 做出了非常明確規範,

要使用 Date.parse()new Date(dateString) 來解析日期格式字串,要用簡化版的 ISO 8601 延伸格式。


ISO 8601 Extended Format 格式:

YYYY-MM-DDTHH:mm:ss.sssZ

這種標準的日期格式,也可以允許只有日期的部分,而且還不一定要寫完整的日期格式,只有年份也可以當成合法有效的日期格

式。以下日期格式都是合法、有效且跨瀏覽器、跨平台的日期字串格式:

new Date('2020');       // Wed Jan 01 2020 08:00:00 GMT+0800 (台北標準時間)
new Date('2020-08');    // Sat Aug 01 2020 08:00:00 GMT+0800 (台北標準時間)
new Date('2020-08-12'); // Wed Aug 12 2020 08:00:00 GMT+0800 (台北標準時間)

時間的部分,日期的部分不能省略,而日期與時間的部分會固定用一個 T 來分隔。時間的部分,從「秒」開始也是可以省略

的,不一定要完整的時間格式,且時間格式最後的 Z 代表的是 Time zone 的意思,這個字元也是可以省略的。

THH:mm
THH:mm:ss
THH:mm:ss.sss

以下示範都是合法有效的日期格式字串:

new Date('2020T04:48');           // Wed Jan 01 2020 04:48:00 GMT+0800 (台北標準時間)
new Date('2020-08T04:48:34');     // Sat Aug 01 2020 04:48:34 GMT+0800 (台北標準時間)
new Date('2020-08-12T04:48:33');  // Wed Aug 12 2020 04:48:33 GMT+0800 (台北標準時間)
new Date('2020-08T04:48:33.346'); // Sat Aug 01 2020 04:48:33 GMT+0800 (台北標準時間)

方法

取得年份

方式是 getFullYear( )

data.getFullYear( ); // 2020

取得月份

方式是 getMonth( )

data.getMonth( )+1;  // 8

注意:getMonth()0 開始計算,所以實際應用時請記得 + 1

取得日期

方式是 getDate( )

data.getDate( );  // 12

取得星期

方式是 getDay( )

data.getDay( )+1; // 3

注意:星期也一樣要注意 getDay( )0 開始計算,所以實際應用時請記得 + 1

如果要把星期數字換成中文字數字:

let weekDayChinese = ["星期日","星期一","星期二","星期三","星期四","星期五","星期六"];
let weekDayStr = weekDayChinese[date.getDay()]; // "星期三"

取得小時

方式是 getHours( )

data.getHours( ); // 18

取得分鐘

方式是 getMinutes( )

data.getMinutes( ); // 7

取得秒數

方式是 getSeconds( )

data.getSeconds( ); // 38

取得毫秒

方式是 getMilliseconds( )

data.getMilliseconds( ); // 323

毫秒的單位是每 1000 秒 = 1 秒。

取得時間戳

方式是 getTime( )

data.getTime( ); // 1597226858323

一般來講實際開發時,很常見於使用時間戳來繼續資料新增的時間與修改時間。


組合成一個年/月/日 時:分:秒

如果我們要將以上方式組合成一個日期,只需要將個別取出來的時間儲存到一個變數內再組合即可:

var time = new Date();
var year = time.getFullYear();
var month = time.getMonth() + 1;
var day = time.getDay() +1 ;
var hours = time.getHours();
var minutes = time.getMinutes();
var sec = time.getSeconds();
var millSec = time.getMilliseconds();

var fullTime = '現在日期與時間:' + year + '/' + month + '/' + day + ' ' + hours + ':' + minutes + ':' + sec + ':' + millSec;

參考文件