<input type="date"> 取得毫秒數與加減天數在之前的 Tool 3 中,我們成功完成了「每日用藥時間表生成器」。但是在照顧長輩或自己管理藥箱時,還有一個極為常見卻容易被忽視的痛點:藥品的保存期限。
像是眼藥水(開封後通常只能放 28 天)、糖漿藥水(開封後約 14 天),或是拆封後的散裝藥丸,這些藥品在開封後就開始倒數計時。如果純靠腦力記憶,很容易放到過期還繼續服用。
從今天開始的 Tool 4:藥品保存期限與動態過期提醒器,我們要來解決這個問題!首先第一步,就是要學會如何在 JavaScript 中處理時間計算與日期的加減法。
在 JS 中處理日期,最核心的就是原生的 Date 物件。許多前端新手第一次碰到日期加減時會感到頭痛,因為字串如 "2026-10-07" 沒辦法直接加上天數。
要理解 JS 的時間運算,只要記住兩個重點:
date.getTime() 會取得自 1970/01/01 以來經歷的毫秒數 (Milliseconds)。因為是純數字,所以可以直接做加減運算。1天 = 24小時 × 60分鐘 × 60秒 × 1000毫秒 = 86,400,000毫秒
只要掌握「將日期轉為毫秒數 → 加上指定天數的毫秒數 → 轉回日期格式」這套公式,就能輕鬆完成任何日期運算
<input type="date"> 取得毫秒數與加減天數HTML5 的 <input type="date"> 提供了一個方便的原生日期選擇器,使用者選完後,預設會傳回 YYYY-MM-DD 格式的字串。
當我們透過 JavaScript 抓取其值時:
input.value:傳回字串(例如 "2026-10-07")。input.valueAsNumber:直接傳回毫秒數(例如 1791331200000),省去了手動轉型為 Date 物件的步驟!input.valueAsDate:直接傳回 JS 的 Date 物件。搭配使用者輸入的自訂效期天數 expiryDays(例如輸入 28 天),我們就能秒算算出過期日期!
以下是 Tool 4 的基礎功能:輸入藥品名稱、選擇開封日期、輸入保存天數,自動計算並顯示預計過期日。
/index.html
<!-- Tool 4: 開瓶倒數計時器 -->
<section id="tool4" class="tool-card">
<h2>特殊藥品開瓶倒數計時器</h2>
<p class="subtitle">針對眼藥水、胰島素等開瓶後效期較短之藥品</p>
<div class="form-grid">
<div class="input-group"><label for=""></label><input type="text"></div>
</div>
<div class="form-grid">
<div class="input-group">
<label for="item-name">藥品/眼藥水名稱</label>
<input type="text" id="item-name" placeholder="例如:青光眼眼藥水">
</div>
<div class="input-group">
<label for="open-date">開瓶日期</label>
<input type="date" id="open-date">
</div>
<div class="input-group">
<label for="expiry-days">效期天數</label>
<input type="number" id="expiry-days" placeholder="例如:28" min="1">
</div>
<button class="btn btn-yellow" id="btn-add-timer">➕ 新增追蹤項目</button>
<button class="btn btn-danger" id="btn-clear-timers">清空所有項目</button>
<div id="timer-list" class="timer-container"></div>
</section>
/tool4-timer.js<input type="date"> 與自訂效期當使用者點擊新增按鈕時,程式會從畫面上的輸入欄位抓取資料:
取得開瓶日期:
const dateInput = document.getElementById("open-date");
const dateStr = dateInput.value; // 取得格式為 "YYYY-MM-DD" 的字串
取得自訂效期與防呆機制:
const expiryInput = document.getElementById("expiry-days");
// 使用三元運算子:若輸入值大於 0 則轉成整數,否則預設為 28 天
const expiryDays = parseInt(expiryInput.value, 10) > 0 ? parseInt(expiryInput.value, 10) : 28;
Date 物件並將時間歸零因為 HTML 的 <input type="date"> 傳回的是字串(例如 "2026-06-01"),必須透過 new Date() 建立 JavaScript 的日期物件才能進行數學運算。
同時,為了避免「小時、分、秒」影響天數計算(例如相差幾小時導致天數計算有誤差),程式會統一將時間歸零:
const today = new Date();
today.setHours(0, 0, 0, 0); // 將今天的時分秒設為 00:00:00
const openDate = new Date(item.openDate); // 將儲存的日期字串轉為 Date 物件
openDate.setHours(0, 0, 0, 0); // 將開瓶日的時分秒也設為 00:00:00
利用兩個 Date 物件相減,JavaScript 會自動將它們轉成毫秒數 (Milliseconds),再透過數學換算成「天數」:
// 1. 計算今天與開瓶日的毫秒差,並換算成天數 (1000毫秒 * 60秒 * 60分 * 24小時)
const diffTime = today - openDate;
const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));
// 2. 兼容舊資料:若該筆資料沒有設定 expiryDays,則預設為 28 天
const totalExpiry = item.expiryDays || 28;
// 3. 計算最終剩餘天數 = 總效期 - 已過天數
const remainDays = totalExpiry - diffDays;
diffDays = 0),總效期 30 天:30 - 0 = 30(剩餘 30 天)。diffDays = 10):30 - 10 = 20(剩餘 20 天)。30 - 35 = -5(剩餘 -5 天,代表已過期 5 天)。許多前端開發者一碰到時間計算,第一反應就是載入 Moment.js 或 Day.js 等第三方套件。但其實像這種「開封日 + 保存天數 = 過期日」的基礎運算,使用原生的 Date 物件與 setDate() 方法就能在幾行內搞定,既節省專拿打包體積,執行效能也更高!
今天我們學會了如何從 <input type="date"> 取值並做天數加減。明天(Day 25),我們要進一步加入倒數天數計算 (Countdown) 與 動態顏色警示 (綠/黃/紅),讓過期提醒更有視覺衝擊力。