Try   HackMD

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 秒。

建立特定時間點的 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

傳入 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 (台北標準時間)

傳入 多個數字

傳入多個數字,指定年、月、日、時、分、秒、毫秒 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)。


轉換

[ 取得 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();

取得秒 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


[ 轉換為 自定義時間格式 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'

時區的顯示

如果沒有在 format 之前特別指定時區,format 出來的結果都會依照使用者當前的時區。所以同一段程式碼,在不同使用者的電腦可能會有不同的輸出。

例如:

luxon.DateTime
  .fromISO('2020-02-02T13:00:00+03:00')
  .toFormat('HH:mm:ss')

// 由於電腦是臺灣 +8 時區,所以結果會是 18:00:00 而不是 13:00:00

因此 Server 端給你什麼都不重要,給你 2020-02-02T13:00:00+03:00 或是 2020-02-02T10:00:00Z2020-02-02T18:00:00+08:00,對前端來說都是一樣的,都代表著同一個時間,用 format 也都會產生出一樣的結果。


[ 取得當地時區 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 中的時間與時區處理 JavaScript Date 時間和日期