Skip to content

你未必需要 moment / date-fns 或 luxon,原生 JavaScript 如何 parse 和 format 日期時間

Published: at 10:54 AM (4 min read)

過去我們習慣使用 moment.js / date-fnsluxon 等套件來處理日期時間,但也許在一些情況下,我們可以簡單使用原生 JavaScript 來達到相同的功能。

Parse - Date

假設你需要 parse 一個 YYYY-MM-DD 格式的日期字串,你可以透過簡單的 regex 來達到:

const datePattern = /^(\d{4})-(\d{2})-(\d{2})$/;
const [, month, day, year] = datePattern.exec("2024-05-21");
new Date(`${month}, ${day} ${year}`);
// Tue May 21 2024 00:00:00 GMT+0800 (Taipei Standard Time)

Parse - Date + Time

原生 Date 物件可以 parse 以下的日期時間字串:

// now
new Date();

// datetime string
new Date("2024-05-21T19:19:00");
// Tue May 21 2024 19:19:00 GMT+0800 (Taipei Standard Time)

// datetime with milliseconds and timezone
new Date("2024-05-21T19:19:00.000+08:00");
// Tue May 21 2024 19:19:00 GMT+0800 (Taipei Standard Time)

// timestamp milliseconds since Unix epoch
new Date(01716289667000);
// Tue May 21 2024 19:07:47 GMT+0800 (Taipei Standard Time)

// ISO 8601 date string
new Date("2024-05-21T11:10:31.057Z");
// Tue May 21 2024 19:10:31 GMT+0800 (Taipei Standard Time)

// Individual date and time component values
new Date(2024, 4, 21, 11, 10, 31, 57);
// Tue May 21 2024 11:10:31 GMT+0800 (Taipei Standard Time)

如果你需要 parse 其他格式,如 YYYY-MM-DD HH:mm:ss 格式的日期時間字串,你可以透過簡單的 regex 來達到:

const datePattern = /^(\d{4})-(\d{2})-(\d{2})\s(\d{1,2}):(\d{2}):(\d{2})$/;
const [, year, month, day, rawHour, min, sec] = datePattern.exec(
  "2024-05-21 10:54:08"
);
new Date(`${year}-${month}-${day}T${("0" + rawHour).slice(-2)}:${min}:${sec}`);
// Tue May 21 2024 10:54:08 GMT+0800 (Taipei Standard Time)

Get

獲得日期時間的 Year, Month, Day, Hour, Minute, Second

const d = new Date("2024-05-21T19:21:58");
// Tue May 21 2024 19:21:58 GMT+0800 (Taipei Standard Time)

// get year
d.getFullYear(); // 2024

// get month
d.getMonth() + 1; // 5

// get day
d.getDate(); // 21

// get hour
d.getHours(); // 19

// get minute
d.getMinutes(); // 21

// get second
d.getSeconds(); // 58

// get day of week
d.getDay(); // 2

Set

設定日期時間的 Year, Month, Day, Hour, Minute, Second

const d = new Date("2024-05-21T19:21:58");
// Tue May 21 2024 19:21:58 GMT+0800 (Taipei Standard Time)

// set year
d.setFullYear(2025);
// Wed May 21 2025 19:21:58 GMT+0800 (Taipei Standard Time)

// set month
d.setMonth(6);
// Sun Jul 21 2024 19:21:58 GMT+0800 (Taipei Standard Time)

// set day
d.setDate(22);
// Wed May 22 2024 19:21:58 GMT+0800 (Taipei Standard Time)

// set hour
d.setHours(22);
// Tue May 21 2024 22:21:58 GMT+0800 (Taipei Standard Time)

// set minute
d.setMinutes(30);
// Tue May 21 2024 19:30:58 GMT+0800 (Taipei Standard Time)

// set second
d.setSeconds(10);
// Tue May 21 2024 19:21:10 GMT+0800 (Taipei Standard Time)

Manipulate

日期時間的加減

const d = new Date("2024-05-21T19:21:58");
// Tue May 21 2024 19:21:58 GMT+0800 (Taipei Standard Time)

// add 1 year
d.setFullYear(d.getFullYear() + 1);
// Wed May 21 2025 19:21:58 GMT+0800 (Taipei Standard Time)

// add 1 month
d.setMonth(d.getMonth() + 1);
// Fri Jun 21 2024 19:21:58 GMT+0800 (Taipei Standard Time)

// add 1 day
d.setDate(d.getDate() + 1);
// Wed May 22 2024 19:21:58 GMT+0800 (Taipei Standard Time)

// add 1 hour
d.setHours(d.getHours() + 1);
// Tue May 21 2024 20:21:58 GMT+0800 (Taipei Standard Time)

// add 1 minute
d.setMinutes(d.getMinutes() + 1);
// Tue May 21 2024 19:22:58 GMT+0800 (Taipei Standard Time)

// add 1 second
d.setSeconds(d.getSeconds() + 1);
// Tue May 21 2024 19:21:59 GMT+0800 (Taipei Standard Time)

// subtract 1 day, other methods are similar
d.setDate(d.getDate() - 1);
// Mon May 20 2024 19:21:59 GMT+0800 (Taipei Standard Time)

Difference

兩個日期時間的差異

const d = new Date("2024-05-21T19:21:58");
// Tue May 21 2024 19:21:58 GMT+0800 (Taipei Standard Time)

// Time from now (days)
const now = new Date();
const diff = now - d;

// in minutes
Math.floor(diff / (1000 * 60));

// in hours
Math.floor(diff / (1000 * 60 * 60));

new Intl.RelativeTimeFormat().format(
  Math.floor(diff / (1000 * 60 * 60 * 24)),
  "day"
);
// in 30 days

Format

原生 Date 物件提供了一些方法來格式化日期時間:

const d = new Date("2024-05-21T19:21:58");
// Tue May 21 2024 19:21:58 GMT+0800 (Taipei Standard Time)

// format to ISO 8601
d.toISOString(); // 2024-05-21T11:21:58.000Z

// format to locale string
d.toLocaleString(); // 5/21/2024, 7:21:58 PM

// format to locale date string
d.toLocaleDateString("zh-TW", {
  year: "numeric",
  month: "long",
  day: "numeric",
}); // 2024年5月21日

// format to locale time string
d.toLocaleDateString("en-US", {
  year: "numeric",
  month: "long",
  day: "numeric",
}); // May 21, 2024

// YYYY-MM-DD
d.toISOString().split("T")[0]; // 2024-05-21

Reference