本文 AI 產出,尚未審核

JavaScript 日期與時間(Date & Time)─ 取得與設定時間

簡介

在前端開發或 Node.js 後端程式中,時間的處理是最常見也最容易出錯的需求。不論是顯示使用者的最後登入時間、計算兩筆資料的相差天數,或是製作倒數計時器,都離不開 Date 物件。

本單元聚焦於 取得與設定時間 的基本操作,讓你能快速抓取現在的時間、拆解成年、月、日、時、分、秒,並且依需求自行調整。掌握這些技巧後,你就能在專案中正確處理時區、毫秒級的計算,並避免常見的時間錯誤。


核心概念

1. 建立 Date 物件

// 取得目前時間(本機時區)
const now = new Date();          // => 2025-11-20T07:30:45.123Z(ISO 格式)
  • new Date() 會回傳一個 代表當前時間的 Date 物件
  • 若傳入字串、數字或其他 Date 物件,可建立對應的時間點。
// 以字串建立(ISO 8601)
const utc = new Date('2025-01-01T00:00:00Z');

// 以毫秒數(Unix epoch)建立
const fromEpoch = new Date(0);   // 1970-01-01T00:00:00.000Z

2. 取得時間資訊

方法 說明 範例
getFullYear() 取得四位數的年份 now.getFullYear()2025
getMonth() 取得月份(0~11,0 為一月) now.getMonth()10(11 月)
getDate() 取得月份中的日期(1~31) now.getDate()20
getHours()getMinutes()getSeconds()getMilliseconds() 取得時、分、秒、毫秒 now.getHours()7
getDay() 取得星期幾(0~6,0 為星期日) now.getDay()4(星期四)
getTime() 取得自 1970-01-01 UTC 起的毫秒數 now.getTime()1732085445123

小技巧:如果需要 UTC 時間,使用 getUTCFullYear()getUTCMonth() 等對應方法。

// 取得現在的完整時間字串(本機時區)
const formatted = `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()} ` +
                  `${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}`;
console.log(formatted);   // 2025-11-20 7:30:45

3. 設定時間資訊

Date 物件是 可變的(mutable),可以直接修改其內部時間。

const d = new Date();   // 現在時間
d.setFullYear(2024);    // 改成 2024 年
d.setMonth(0);          // 改成 1 月(0 代表一月)
d.setDate(15);          // 改成 15 日
d.setHours(23, 59, 59, 999); // 同時設定時、分、秒、毫秒
console.log(d.toISOString()); // 2024-01-15T23:59:59.999Z(假設時區為 UTC)
  • setFullYear(year [, month [, day]])setMonth(month [, day])setDate(day) 等方法都支援 多參數,一次設定多個欄位。
  • 設定值超出正常範圍時,Date 會自動 進位或退位(例如 setMonth(12) 會跳到下一年的一月)。
const overflow = new Date(2025, 0, 31); // 2025-01-31
overflow.setDate(32);   // 超過當月天數,會變成 2025-02-01
console.log(overflow.toDateString()); // Sun Feb 01 2025

4. 以毫秒為基礎的運算

因為 Date 內部以 UTC 毫秒 儲存,進行時間差或加減時,直接操作毫秒最直觀。

const start = new Date();               // 開始時間
// 兩小時後的時間
const twoHoursLater = new Date(start.getTime() + 2 * 60 * 60 * 1000);
console.log(twoHoursLater.toLocaleString());

// 計算兩個日期的天數差
function diffInDays(a, b) {
  const msPerDay = 24 * 60 * 60 * 1000;
  return Math.round(Math.abs(a - b) / msPerDay);
}
console.log(diffInDays(new Date('2025-12-01'), new Date('2025-11-20'))); // 11

程式碼範例

範例 1️⃣:取得現在的本地時間與 UTC 時間

// 本機時間
const local = new Date();
console.log('本機時間:', local.toString());

// UTC 時間
console.log('UTC 時間:', local.toUTCString());

// 只取出時間部份(HH:MM:SS)
const timeStr = `${local.getHours().toString().padStart(2, '0')}:` +
                `${local.getMinutes().toString().padStart(2, '0')}:` +
                `${local.getSeconds().toString().padStart(2, '0')}`;
console.log('現在時間(HH:MM:SS):', timeStr);

重點toString() 依本機時區呈現,toUTCString() 則固定為 UTC。

範例 2️⃣:自訂生日倒數計時(天、時、分、秒)

function countdown(target) {
  const now = new Date();
  const diff = target - now;               // 毫秒差
  if (diff <= 0) return '生日快樂 🎉';

  const days    = Math.floor(diff / (24*60*60*1000));
  const hours   = Math.floor((diff % (24*60*60*1000)) / (60*60*1000));
  const minutes = Math.floor((diff % (60*60*1000)) / (60*1000));
  const seconds = Math.floor((diff % (60*1000)) / 1000);

  return `${days} 天 ${hours} 時 ${minutes} 分 ${seconds} 秒`;
}

// 設定生日:2025-12-25 00:00:00(本機時區)
const birthday = new Date(2025, 11, 25);
console.log('距離生日還有:', countdown(birthday));

範例 3️⃣:將 ISO 8601 字串轉成本地時間字串

function isoToLocal(isoStr) {
  const d = new Date(isoStr);   // 解析 ISO 字串(自動視為 UTC)
  // 以本機時區格式化
  return d.toLocaleString('zh-TW', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
    hour12: false
  });
}

const iso = '2025-03-15T12:30:00Z';
console.log('本機時間顯示:', isoToLocal(iso));

範例 4️⃣:自動補零(padStart)與時間格式化函式

function formatTime(date) {
  const y = date.getFullYear();
  const m = String(date.getMonth() + 1).padStart(2, '0');
  const d = String(date.getDate()).padStart(2, '0');
  const h = String(date.getHours()).padStart(2, '0');
  const min = String(date.getMinutes()).padStart(2, '0');
  const s = String(date.getSeconds()).padStart(2, '0');
  return `${y}-${m}-${d} ${h}:${min}:${s}`;
}

console.log('格式化時間:', formatTime(new Date()));

範例 5️⃣:利用 setHours 快速調整時區差(簡易時區轉換)

// 假設伺服器回傳的時間是 UTC,前端要顯示台北時間 (+8)
function utcToTaipei(utcDate) {
  const local = new Date(utcDate);
  // 加上 8 小時
  local.setHours(local.getHours() + 8);
  return local;
}

const utcNow = new Date(); // 假設是 UTC
const taipeiNow = utcToTaipei(utcNow);
console.log('UTC:', utcNow.toISOString());
console.log('台北時間:', taipeiNow.toLocaleString());

常見陷阱與最佳實踐

陷阱 說明 建議的做法
月份從 0 開始 new Date(2025, 0, 1) 代表 1 月,易把 0 當成「沒有月份」 永遠記得+1 於顯示或輸入時
字串解析不一致 new Date('2025-11-20') 在不同瀏覽器可能被視為本機時區或 UTC 使用 ISO 8601 完整格式2025-11-20T00:00:00Z)或 Date.parse 前先確認時區
毫秒溢位 setMilliseconds(1500) 會自動進位成 1.5 秒,但不易直觀 使用毫秒加法date.setTime(date.getTime() + 1500)
時區差異導致日期變化 跨時區顯示時,toDateString() 可能因時區轉換而變成前一天 使用 toLocaleString 並明確指定時區(timeZone: 'Asia/Taipei'
Date.now() vs new Date() Date.now() 直接回傳毫秒數,效能較佳 計算時間差 時優先使用 Date.now(),僅在需要完整日期物件時才 new Date()

最佳實踐

  1. 統一時區:在後端與前端約定使用 UTC,顯示層再轉成本地時區。
  2. 避免直接比較字串:使用毫秒數 (getTime()Date.now()) 進行比較。
  3. 封裝日期工具:將常用的格式化、時區轉換、差值計算寫成模組,避免重複程式碼。
  4. 使用 Intl.DateTimeFormat:在需要多語系或自訂格式時,Intl 提供更彈性的國際化支援。
const fmt = new Intl.DateTimeFormat('zh-TW', {
  year: 'numeric',
  month: 'short',
  day: 'numeric',
  hour: '2-digit',
  minute: '2-digit',
  timeZone: 'Asia/Taipei'
});
console.log('Intl 格式化:', fmt.format(new Date()));

實際應用場景

  1. 訂單系統的交易時間戳記

    • 使用 Date.now() 產生毫秒級唯一 ID,儲存於資料庫。
    • 前端顯示時,使用 toLocaleString 依使用者時區呈現。
  2. 活動倒數計時器

    • 透過 setInterval 每秒更新 countdown(),讓使用者即時看到剩餘時間。
  3. 日誌(Log)檔的時間標記

    • new Date().toISOString() 產生標準化的 UTC 時間,方便跨系統比對。
  4. 跨時區會議排程

    • 先將所有會議時間轉成 UTC,存入資料庫。
    • 使用者登入後,以 Intl.DateTimeFormat 依所在時區顯示正確時間。
  5. 生日或周年慶提醒

    • 每日跑一次批次任務,計算 diffInDays,若相差 0 天則發送推播或 Email。

總結

  • Date 物件是 JavaScript 處理時間的核心工具,取得設定時間的 API 大多以 本機時區 為基礎,必要時可切換到 UTC
  • 透過 get*set* 方法、毫秒運算以及 Intl 國際化 API,我們可以精確、彈性地完成各種時間需求。
  • 常見的月份起始、字串解析與時區差異問題,只要遵守 統一時區、使用完整 ISO 格式、封裝工具函式 的最佳實踐,就能大幅降低錯誤率。

掌握了「取得與設定時間」的技巧後,你將能在 訂單系統、倒數計時、跨時區排程 等實務場景中,寫出可靠且易於維護的程式碼。祝你在 JavaScript 的時間旅程中,秒秒精準、毫毫不錯