# JavaScript Date 時間和日期 ###### tags: `javaScript` `dateTime` ## 儲存時間的標準格式 > 時間是相對性的。 #### `timestamp` > 1481361366000,肉眼不好分辨。 - 表示從 1970-01-01 00:00:00 UTC (格林威治標準時間) 開始累計到某時間點的毫秒數 (milliseconds) - 1593163158 這個 timestamp 代表的是: 「UTC +0 時區的 2020-06-26 09:19:00」,同時也代表著 「UTC +8 時區的 2020-06-26 17:19:00」,這兩個時間是一樣的,都是同一個時間。 - 所以當你拿到一個 timestamp 以後,你無法從 timestamp 本身知道你應該要顯示成什麼時區的時間。 #### `ISO 8601` > 2020-12-26T12:38:00Z 一種 date-time 格式 - 如果是 Z 就代表 UTC +0 - 如果要其他時區可以這樣寫:2020-12-26T12:38:00+08:00,代表 +8 時區的 12 月 26 號 12 點 38 分 0 秒。 <br /> ## 建立特定時間點的 Date 物件 用 new Date(string) 就等於 Date.parse(string) ### 建立當前 date time object > Date 物件參數的日期,預設的時區 (time zone) 是本地時區 (local time),也就是你瀏覽器作業系統設定的時區。 產生 GMT+8 時間的字串 ``` const today = new Date(); // Sat Dec 10 2016 17:16:06 GMT+0800 (台北標準時間) ``` 產生 ISO 8601 格式的字串 UTC+0 ``` const today = new Date().toISOString(); // 2020-12-26T04:52:26.255Z ``` <br /> ### 傳入 Timestamp 數字 > Timestamp >> 表示從 1970-01-01 00:00:00 UTC (格林威治標準時間) 開始累計到某時間點的毫秒數 (milliseconds) ``` new Date(timestamp); const date = new Date(1481361366000); // Sat Dec 10 2016 17:16:06 GMT+0800 (台北標準時間) ``` <br /> ### 傳入 多個數字 > 傳入多個數字,指定年、月、日、時、分、秒、毫秒 > JavaScript 支援所有可以被 parse 的時間格式,詳細請看 parse() 方法的介紹。 ``` new Date(year, month[, date[, hours[, minutes[, seconds[, milliseconds]]]]]); var birthday = new Date(1995, 11, 17); // Sun Dec 17 1995 00:00:00 GMT+0800 (CST) ``` - 月份 (month) >> 是從 0 到 11,0 是一月;11 是十二月。 - 時 (hours) >> 採 24 小時制 - 如果傳入的日期和時間參數超出正常範圍,例如月份輸入 13,秒數輸入 80,JavaScript 會自動增減做進位。 例如 >> new Date(2018, 13, 1) 會被看作是 new Date(2019, 1, 1);new Date(2016, 9, 10, 0, 80) 會被看作是 new Date(2016, 9, 10, 1, 20)。 <br /> <br /> ## 轉換 ### [ 取得 Timestamp & Unix Timestamp ] #### 取得毫秒 Timestamp,有 4 種方法,回傳都一樣。 ``` const miniGetTime = new Date().getTime(); const miniGetTime = +new Date(); const miniTime = Date.now(); ``` 使用 moment ``` // 當前 timestapm const mm = moment().valueOf(); const mm = +moment(); // 指定時段轉換為 timestamp const mm = moment('2016-01-01').valueOf(); ``` <br /> #### 取得秒 Unix Timestamp ``` const dateTime = new Date().getTime(); const unixTimestamp = Math.floor(dateTime / 1000); ``` ``` const dateTime = +new Date('2012-06-08'); const unixTimestamp = Math.floor(dateTime / 1000); ``` ``` const dateTime = Date.now(); const unixTimestamp = Math.floor(dateTime / 1000); ``` 使用 moment ``` // 當前 unix const unixTimestamp = moment().unix(); // 指定時段轉換為 unix const unixTimestamp = moment('2016-01-01').unix(); // 1451577600 ``` <br /> ### [ 轉換為 自定義時間格式 Format ] #### Timestamp Format ``` const timestamp = 1624871919495; const date = moment(timestamp).format('YYYY-MM-DD'); // '2021-06-28' ``` #### Unix Timestamp Format ``` const unixTimestamp = 1624871712; const date = moment.unix(unixTimestamp).format('YYYY-MM-DD'); // '2021-06-28' ``` <br /> ## 時區的顯示 如果沒有在 format 之前特別指定時區,format 出來的結果都會依照使用者當前的時區。所以同一段程式碼,在不同使用者的電腦可能會有不同的輸出。 例如: ``` luxon.DateTime .fromISO('2020-02-02T13:00:00+03:00') .toFormat('HH:mm:ss') // 由於電腦是臺灣 +8 時區,所以結果會是 18:00:00 而不是 13:00:00 ``` :::: info 因此 Server 端給你什麼都不重要,給你 `2020-02-02T13:00:00+03:00` 或是 `2020-02-02T10:00:00Z` 或 `2020-02-02T18:00:00+08:00`,對前端來說都是一樣的,都代表著同一個時間,用 format 也都會產生出一樣的結果。 :::: <br /> ### [ 取得當地時區 Lacol time zone ] `getTimezoneOffset()` 方法傳回當地時區與UTC時間的時區差,傳回的值是以`分鐘`為單位。以台灣來說,時區是UTC +8,傳回的值是-480。 Q: 到底是 GMT+8 還是 UTC+8 ? A: 現在的標準基本上都是 UTC 了 ``` const tz = new Date().getTimezoneOffset(); // -480 ( -480/60 = -8 ) ``` 使用 moment ``` const tz = moment().utcOffset(); // 480 ``` 提供isLocal切換是否顯示當地時區,預設true,false則顯示+8時區 ``` export const getTimezone = (isLocal = true) => { return isLocal ? -(new Date().getTimezoneOffset() / 60) : 8; }; ``` ##### 參考: [淺談 JavaScript 中的時間與時區處理](https://blog.techbridge.cc/2020/12/26/javascript-date-time-and-timezone/) [JavaScript Date 時間和日期](https://www.fooish.com/javascript/date/)