만 나이, 한국 나이, 생일 계산기 만들기 (1) 로직편

Wonkook Lee·2021년 8월 22일
9

Frontend Exercises

목록 보기
4/7
post-thumbnail

내가 99년생이었으면 좋겠다


만 나이, 한국 나이, 생일 계산기 만들기 (1) 로직편


저번 주 부트캠프에서 치렀던 테스트 중 만 나이를 계산하는 문제가 있었다.
만 나이를 계산하는 로직을 짜는 김에 한국 나이와, 다음 생일까지 남은 일 수를 구하는 계산기를 직접 만들어보고 싶었다.

실생활에 흔히 사용되는 기능을 직접 코드로 풀어가면서 JavaScript의 Date 객체를 이해하고 활용할 수 있게 되었다. 개인적인 경험으로는 사소한 것이라도 직접 만들어보면서 친해지는 것이 효과적이고 효율적이었다.




문제의 정의


🎂 만 나이와 한국식 나이 계산의 차이점

한국식 나이 계산법은 East Asian age reckoning이라고도 불리며 태어난 순간부터 1살, 생일이 지나건 지나지 않았건 매 해를 넘기면 한 살씩 먹는다.

우리가 말하는 만 나이란 생후 첫 돌에 비로소 한 살이 되고, 매년 생일이 되어야 한 살씩 먹어간다.

외국 사람과 나이 관련해서 이야기했던 적이 있는데, 만 나이가 국제적인 나이(International age) 아니냐고 말했더니 그딴거 없고 한국만 이런 식으로 나이를 계산한다고 했다.




만 나이와 한국 나이 구하기


✅ 기초 데이터 변수에 할당

  • YYYY-MM-DD 형식의 매개 변수를 넣어 생년월일 기준 Date 객체를 만든 것이 birthData
  • 현재 시각을 기준으로 만든 Date객체가 할당된 currentData
const calcAge = (input) => {
  const birthData = new Date(input);
  const currentData = new Date();
}

🇰🇷 한국식 나이 구하기

한국식 나이 계산은 태어난 해를 1살로 치고, 생일이 지났는지와 관계 없이 계산하는 해의 1월 1일 자정이 지나면 1살을 더한다.

const koreanAge = currentData.getFullYear() - birthData.getFullYear() + 1;

한국식 나이 계산은 간단하다. 기준일의 연도에서 생년을 빼준 후 한 살을 더해주면 된다.


🎂 만 나이 구하기

만 나이 계산(일반적인 나이 계산)은 생 후 첫번째 생일이 되어야 1살이 되며, 나이를 계산하는 해에 생일이 지나야 비로소 1살을 더한다.

const realAge = new Date(currentData - birthData).getFullYear() - 1970;

⏳ Date 객체끼리의 연산 단위는 밀리세컨즈

Date 객체끼리도 연산이 가능하다. 타임스탬프(밀리세컨즈, 1/1000초)로 변환되어 연산을 수행한다. 연산 결과를 연도로 산출하려면 다시 Date 생성자의 인자로 연산 결과를 넣어주어야 한다.

자바스크립트에서 타임스탬프는 1970년 1월 1일 자정으로부터 경과된 밀리세컨즈를 의미하기 때문에 다시 1970을 빼주어야 원하는 결과를 얻을 수 있다.


⚠️ 주의할 점

현재 시간을 담은 Date객체는 시, 분, 초 까지 포함하고 있다. 하지만 생년월일을 담은 Date 객체는 시간을 포함하지 않고 자정으로 Set 되어있다. 따라서 setHours() 메소드로 현재 시간 객체의 시간 정보를 리셋할 필요가 있다.

// Syntax
setHours(hoursValue);
setHours(hoursValue, minutesValue);
setHours(hoursValue, minutesValue, secondsValue);
setHours(hoursValue, minutesValue, secondsValue, msValue);

🌟 적용 및 완성

아래 함수는 YYYY-MM-DD 포맷의 생일 정보를 인자로 전달받고, 나이와 한국 나이를 객체에 담아 반환한다.

const calcAge = input => {

	const birthData = new Date(input);
	const currentData = new Date();
  currentData.setHours(0, 0, 0, 0);

	// 나이 계산
	const realAge = new Date(currentData - birthData).getFullYear() - 1970; // 만 나이 계산하기

	const koreanAge = currentData.getFullYear() - birthData.getFullYear() + 1; // 한국 나이 계산하기

	return {
		realAge: realAge,
		koreanAge: koreanAge,
	}
};



다음 생일까지 남은 일 수 계산하기


🤔 원하는 것

  • 올해 생일이 지나지 않았다면 올해의 생일까지 남은 일 수를 반환한다.
  • 올해 생일이 지났다면 내년 생일까지 남은 일 수를 반환한다.

🥳 올해 생일이 지났는지, 남았는지 어떻게 알 수 있을까?

한국식 나이 계산에서 만 나이를 빼면 아래와 같다

  • 올해 생일이 지났을때 -> 한국 나이 - 만 나이 = 1
  • 올해 생일이 지나지 않았을때 -> 한국 나이 - 만 나이 = 2

위 명제는 아래의 조건문으로 표현할 수 있다.

if (koreanAge - 2 === realAge) { ... }
else if (koreanAge - 1 === realAge) { ... }

🧮 날짜 연산

아래와 같은 프로세스로 Date 객체의 연산을 활용한다.

  • 현 시각을 나타내는 날짜 객체를 만든다 (1)
  • 생년월일 중 생년만 현재 연도로 수정한 날짜 객체를 만든다. (2)
  • 만약 생일이 지났을 경우 내년 생일까지 남은 시간을 계산해야 하므로 매개 변수 correction을 넣는다. (생일이 지나지 않았을 경우 + 0 / 지났으면 + 1)
const timeDifference = correction => {
	return currentData - new Date(birthData.setFullYear(currentData.getFullYear() + correction))
};

currentData (현재 시각 날짜 객체)
new Date(birthData.setFullYear(currentData.getFullYear() + correction)) (생일 기준 날짜 객체에서 생년을 현재 연도로 수정)


🔗 조건문과 날짜 연산 연동하기

아래 조건에 따라 올해 생일이 지나지 않았을 경우 (한국나이 - 만나이 = 2)와 올해 생일이 지났을 경우 (한국나이 - 만나이 = 1) 내년 생일까지 남은 날짜를 변수 result에 밀리세컨즈 단위로 할당한다.

let result;
if (koreanAge - 2 === realAge) {
	result = timeDifference(0); // 올해 생일이 지나지 않은 경우
} else if (koreanAge - 1 === realAge) {
	result = timeDifference(1); // 올해 생일이 지나 내년 생일까지 계산
}

🔢 결과값 정수로 변환하기

위 연산 결과를 음수에서 양수로, 밀리세컨즈 단위에서 일 단위로 변환해야한다.
양수로 바꾸는 것은 Math.abs 메소드를 사용하고, 하루는 3600분, 1분은 1000 밀리세컨즈이기 때문에 역으로 다시 나눠준다.
시간의 차이는 상관 없으니 Math.floor로 정수를 만든다.

let remaining;
.
.
remaining = Math.abs(Math.floor(result / 1000 / 3600 / 24));



🎉 오늘 생일인지 확인하기

만약 오늘이 생일이라면 생일까지 남은 날짜를 담은 변수 remaining이 365가 되어야 한다. 즉 오늘이 생일이기 때문에 다음 생일까지 365일이 남은 것이다.

let today;
.
.
today = remaining === 365 ? true : false;



📦 결과를 객체로 반환하기

만 나이, 한국 나이, 다음 생일까지 남은 날짜, 오늘 생일 여부를 객체 정보로 담아 반환한다. 필요한 정보를 객체로 묶어서 반환하는 편이 사용하기 용이하기 때문이다.

return {
	realAge: realAge,
	koreanAge: koreanAge,
	remainingAge: remaining,
	isTodayBirthday: today
}



✨ 정리

const calcAge = input => {

  const birthData = new Date(input);
  const currentData = new Date();
  currentData.setHours(0, 0, 0, 0);


  // 나이 계산
  const realAge = new Date(currentData - birthData).getFullYear() - 1970; // 만 나이 계산하기
  const koreanAge = currentData.getFullYear() - birthData.getFullYear() + 1; // 한국 나이 계산하기

  // 다음 생일까지 날짜 계산
  const timeDifference = correction => {
    return currentData - new Date(birthData.setFullYear(currentData.getFullYear() + correction));
  }
  
  let result, today, remaining;
  if (koreanAge - 2 === realAge) { // 생일이 지나지 않았음 (올해 생일까지 몇 일?)
    result = timeDifference(0);
  } else if (koreanAge - 1 === realAge) { // 생일이 지났음 (내년 생일까지 몇 일?)
    result = timeDifference(1);
  }
  remaining = Math.abs(Math.floor(result / 1000 / 3600 / 24));
  today = remaining === 365 ? true : false;

  // 객체 반환
  return {
    realAge: realAge,
    koreanAge: koreanAge,
    remainingDays: remaining,
    isTodayBirthday: today,
  }
};
};



ⓒ Wonkook Lee

🙏🏻 잘못된 정보가 있다면 지적해주세요

profile
© 가치 지향 프론트엔드 개발자

2개의 댓글

comment-user-thumbnail
2021년 8월 30일

오늘도 재밌게 보고 갑니다 쇽쇽

1개의 답글