JS 計算年齡:生日沒過就減一的寫法與 3 個坑

Vous voulez vous détendre un peu ? Alors venez proposer des jeux, ou simplement participer à des jeux déjà mis en place !
Répondre
Lucas01
Utilisateur
Messages : 32
Enregistré le : mar. 3 déc. 2024 04:25

JS 計算年齡:生日沒過就減一的寫法與 3 個坑

Message par Lucas01 » mer. 28 oct. 2026 06:31

要在 JavaScript 裡算出週歲,核心判斷只有一句:先用「基準年 − 出生年」拿到初步歲數,再比對「今年生日的月日有沒有過」,沒過就減一。開工前不妨先用 年齡計算 產生幾組已知答案的案例,之後拿來當測試基準會省很多時間。

JS 計算年齡的核心判斷:先比年份、再比月日

先把兩個日期拆成年、月、日三個數字來比:

function calcAge(birth, base = new Date()) {
let age = base.getFullYear() - birth.getFullYear();
const m = base.getMonth() - birth.getMonth();
if (m < 0 || (m === 0 && base.getDate() < birth.getDate())) {
age--; // 今年生日還沒到,減一
}
return age;
}


邏輯上就是 年齡計算公式 用的同一套規則,只是搬到程式裡實作。常見的錯誤替代方案是「(今日 − 出生日期) / 365 再取整」:一年有 365 或 366 天,除下來的結果在閏年前後會飄,而且它抓不到「生日當天才算滿一歲」的分界——2000/01/01 出生的人,在 2025/12/31 用天數除法會算成 26 歲,正確答案是 25。要做 實際年齡計算,年月日逐項比對才是穩的做法。

另一個坑是把基準日寫死成 new Date()。如果你在做報表凍結、保單審核或後台名册的歷史快照,基準日應該當成參數傳進來,而不是每次呼叫都抓當下時間,不然隔天重跑數字就變了。

字串生日怎麼解析?Invalid Date 與時區差一天怎麼辦

使用者輸進來的多半是字串,直接拿字串相減會出事。解析後第一件事是檢查有效性:

const d = new Date("1990/05/15");
if (isNaN(d.getTime())) throw new Error("生日格式無效");


格式方面,1990/05/15 與 ISO 的 1990-05-15 在主流瀏覽器都解析得動,但 05-15-1990 這類寫法就沒有保障。台灣系統還有一個特有狀況:身分證或戶政資料常見的是民國年(例如 790515),要先 +1911 轉成西元年再組成日期,不要讓使用者自己換算。

時區則是另一個隱形殺手。new Date("1990-05-15") 會被解讀成 UTC 午夜,在 UTC+8 的台灣環境換算成本地時間是早上 8 點,通常沒問題;但如果伺服器跑在 UTC、或你用 toISOString().slice(0,10) 取日期,跨時區就可能被偏移成前一天,生日當天被誤判成「還沒過」。比較保險的作法是自己用正則把年月日抓出來,直接比三個數字,完全不經過 Date 的時區轉換。

2月29日與只有年月:邊界情況先約定再寫進程式

2/29 出生的人在非閏年沒有標準答案。實務上要先跟產品或承辦單位約定好「視為 2/28」或「視為 3/1」,再把規則寫死在程式裡,例如非閏年時把生日月日設成 3/1 去比對。沒有共識就先上線,隔年客戶打電話來吵機率不小。

另一種常見輸入是只填出生年月、缺日期。這種情況無法判斷生日是否已過,只能回傳近似整歲,而且介面上要明確標示「約 ○ 歲(估算)」,別讓使用者誤以為是精確週歲。

上線前建議用一組已知案例核對,四筆至少各測一次:生日已過、生日未到、生日當天、2/29 出生。手邊沒有現成案例的話,也可以用 計算年齡 產生幾組,對完答案再把資料填進測試檔。

這套寫法適合誰?有什麼局限

這套邏輯適合三種場景:註冊表單的年齡欄位校驗、後台名册自動算齡、以及自製的小型算齡工具。它的輸入單純、規則明確,程式碼十幾行就能搞定。

但它不適合直接拿來做法定資格認定。保險年齡、入學年齡切分、補助門檻這類事項,各有主管機關公告的基準日與計算方式(有的按「周年」、有的按「年次」甚至「學年度」),程式算出來的結果只能當交叉核對的參考,最終還是要依規定辦理。若你的案子涉及保險,可先用 保險年齡計算機 對一下數字,再回到合約條款確認。

最後提醒:上面這段程式碼是示範核心邏輯,不是唯一標準答案。邏輯對了,仍要依你自己專案的輸入格式(民國年?西元年?有沒有只填年月?)與邊界規則(2/29 怎麼算?)調整過、測過,才算真的能上線。

Répondre

Retourner vers « Espace jeux »

cron