JavaScript에서 나이 계산 오류를 멈추세요: 윤년, 2월 29일, 그리고 1월 31일 함정

발행: (2026년 2월 9일 오전 10:18 GMT+9)
3 분 소요
원문: Dev.to

Source: Dev.to

대부분의 연령 계산기가 틀린 이유

  • 단순히 nowYear - dobYear만 계산하고 생일이 이미 지났는지 확인하지 않는다.
  • 모든 달을 같은 길이로 취급한다.
  • 2월 29일 생일에서 오류가 발생한다.
  • JavaScript의 “1월 31일 + 1개월 = 3월”이라는 놀라운 동작에 걸린다.

배포 가능한 연령 계산기가 필요하다면, 이러한 엣지 케이스들을 올바르게 처리해야 합니다.

실제로 우리가 계산하려는 것

주어진 값

  • dob – 생년월일
  • asOf – 연령을 측정하고 싶은 날짜 (기본값은 오늘)

우리가 원하는 결과

  • years – 완전한 생일이 지난 횟수
  • months – 마지막 생일 이후 지난 전체 개월 수
  • days – 그 월 기준점 이후 남은 일수

만약 asOf = dob);

// ---- Years ----
let years = asOf.getFullYear() - dob.getFullYear();
const bdayThisYear = birthdayInYear(dob, asOf.getFullYear(), "FEB_28");
if (asOf  {
  it("handles birthday not yet happened this year", () => {
    const dob = new Date("2000-10-20");
    const asOf = new Date("2026-02-09");
    const r = calculateAge(dob, asOf);
    expect(r.years).toBe(25);
  });

  it("handles month‑end clamping (Jan 31)", () => {
    const dob = new Date("2000-01-31");
    const asOf = new Date("2000-03-01");
    const r = calculateAge(dob, asOf);
    // If your month add is buggy, this often breaks.
    expect(r.years).toBe(0);
    expect(r.months).toBeGreaterThanOrEqual(1);
  });

  it("handles Feb 29 birthdays with FEB_28 rule", () => {
    const dob = new Date("2004-02-29");
    const asOf = new Date("2025-02-28");
    const r = calculateAge(dob, asOf);
    // Under FEB_28 policy, birthday is considered reached on Feb 28.
    expect(r.years).toBe(21);
  });

  it("rejects asOf before dob", () => {
    const dob = new Date("2020-01-01");
    const asOf = new Date("2019-12-31");
    expect(() => calculateAge(dob, asOf)).toThrow();
  });
});

추가로 넣을 수 있는 엣지 케이스

  • dob = 1999-12-31, asOf = 2000-01-01
  • dob = 2000-02-28, asOf = 2001-02-28
  • dob = 2000-03-31, asOf = 2000-04-30

핵심 정리

정확한 연령을 출력하려면:

  1. 정규화 – 날짜만(자정)으로 맞춘다.
  2. 정의 – 일관된 2월 29일 정책을 설정한다.
  3. 클램프 – 월을 이동할 때 월 말일을 조정한다.
  4. 테스트 – 특이한 날짜들을 포괄하는 테스트를 작성한다.

이것만 하면 외부 라이브러리 없이도 동작합니다.

데모 (선택):

Back to Blog

관련 글

더 보기 »

Var vs Let: 큰 혼란을 풀어보자!

‘Var vs Let: The Big Confusion Explained!’ 표지 이미지 https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A...