iT邦幫忙

2026 iThome 鐵人賽

DAY 24
0
自我挑戰組

Vscode 實作:用 HTML/CSS/JS 打造醫藥健康小工具箱系列 第 24 篇

Day 24:【JS 語法】Date 物件與自訂效期:取得 <input type="date"> 與自訂效期天數 (expiryDays)

  • 分享至 

  • xImage
  •  

本篇文章目錄

  1. 前言:從日常用藥到「藥品保存期限」提醒
  2. JavaScript 原生 Date 物件:時間運算的核心機制
  3. 表單互動:從 <input type="date"> 取得毫秒數與加減天數
  4. 程式碼實作:藥品開封日與過期日自動計算
  5. 結語

1. 前言:從日常用藥到「藥品保存期限」提醒

在之前的 Tool 3 中,我們成功完成了「每日用藥時間表生成器」。但是在照顧長輩或自己管理藥箱時,還有一個極為常見卻容易被忽視的痛點:藥品的保存期限。

像是眼藥水(開封後通常只能放 28 天)、糖漿藥水(開封後約 14 天),或是拆封後的散裝藥丸,這些藥品在開封後就開始倒數計時。如果純靠腦力記憶,很容易放到過期還繼續服用。

從今天開始的 Tool 4:藥品保存期限與動態過期提醒器,我們要來解決這個問題!首先第一步,就是要學會如何在 JavaScript 中處理時間計算與日期的加減法。


2. JavaScript 原生 Date 物件:時間運算的核心機制

在 JS 中處理日期,最核心的就是原生的 Date 物件。許多前端新手第一次碰到日期加減時會感到頭痛,因為字串如 "2026-10-07" 沒辦法直接加上天數。

要理解 JS 的時間運算,只要記住兩個重點:

  1. 時間戳記 (Timestamp):
    呼叫 date.getTime() 會取得自 1970/01/01 以來經歷的毫秒數 (Milliseconds)。因為是純數字,所以可以直接做加減運算。
  2. 1 天的毫秒數:

1天 = 24小時 × 60分鐘 × 60秒 × 1000毫秒 = 86,400,000毫秒

只要掌握「將日期轉為毫秒數 → 加上指定天數的毫秒數 → 轉回日期格式」這套公式,就能輕鬆完成任何日期運算

3. 表單互動:從 <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 天),我們就能秒算算出過期日期!

4. 程式碼實作:藥品開封日與過期日自動計算

以下是 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

1. 取得 <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;
    

2. 將字串轉為 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

3. 計算已過天數與剩餘效期

利用兩個 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 天)。
    • 若已經過了 10 天(diffDays = 10):30 - 10 = 20(剩餘 20 天)。
    • 若過了 35 天:30 - 35 = -5(剩餘 -5 天,代表已過期 5 天)。

5. 結語

許多前端開發者一碰到時間計算,第一反應就是載入 Moment.js 或 Day.js 等第三方套件。但其實像這種「開封日 + 保存天數 = 過期日」的基礎運算,使用原生的 Date 物件與 setDate() 方法就能在幾行內搞定,既節省專拿打包體積,執行效能也更高!

今天我們學會了如何從 <input type="date"> 取值並做天數加減。明天(Day 25),我們要進一步加入倒數天數計算 (Countdown) 與 動態顏色警示 (綠/黃/紅),讓過期提醒更有視覺衝擊力。


上一篇
Day 23:【CSS 技巧】列印樣式優化:用 @media print 自動帶入當日日期並一鍵乾淨列印成紙本
下一篇
Day 25:【Tool 4 實作】倒數邏輯與動態進度條:依自訂效期計算剩餘百分比與 CSS 警示燈號切換
系列文
Vscode 實作:用 HTML/CSS/JS 打造醫藥健康小工具箱 共 25 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言