유명 SNS 게시물을 보면 작성 날짜 항목에 "방금 전", "몇분 전", "몇시간 전", "몇일 전"에 작성됨, 과 같은 형식으로 표현하는 것을 볼 수 있습니다.
코드
function elapsedTime(date) {
const start = new Date(date);
const end = new Date();
const diff = (end - start) / 1000;
const times = [
{ name: '년', milliSeconds: 60 * 60 * 24 * 365 },
{ name: '개월', milliSeconds: 60 * 60 * 24 * 30 },
{ name: '일', milliSeconds: 60 * 60 * 24 },
{ name: '시간', milliSeconds: 60 * 60 },
{ name: '분', milliSeconds: 60 },
];
for (const value of times) {
const betweenTime = Math.floor(diff / value.milliSeconds);
if (betweenTime > 0) {
return `${betweenTime}${value.name} 전`;
}
}
return '방금 전';
}
elapsedTime('2022-11-15');
코드 풀이
function elapsedTime(date) {
const start = new Date(date);
const end = new Date(); // 현재 날짜
const diff = (end - start) / 1000; // 경과 시간 구하기 (밀리초 기본으로 빼주기)
경과시간을 구하기 위해서는 비교할 날짜와 현재 날짜가 필요로 합니다. 그러므로 함수 파라미터 값으로 비교할 날짜 정보를 받아와 줍니다. 그다음 현재 날짜와 비교할 날짜 사이의 경과 시간 값을 구해줍니다.
const times = [
{ name: '년', milliSeconds: 60 * 60 * 24 * 365 },
{ name: '개월', milliSeconds: 60 * 60 * 24 * 30 },
{ name: '일', milliSeconds: 60 * 60 * 24 },
{ name: '시간', milliSeconds: 60 * 60 },
{ name: '분', milliSeconds: 60 },
];
// 아래 코드를 위해서는 (년 ~ 분) 순서여야함
이제 "몇분 전", "며칠 전" 등과 같은 시간을 표시하기 위해서 배열에 차례대로 시간 명칭과 해당하는 밀리초 값을 구분 지어 작성해주고
아래 반복문 코드를 위해서 대소 관계를 비교하기 위해서 [년도 ~ 분] 순서로 코드를 작성해줍니다.
// 년 단위부터 알맞는 단위 찾기
for (const value of times) {
const betweenTime = Math.floor(diff / value.milliSeconds);
// 큰 단위는 0보다 작은 소수점 값이 나옴
if (betweenTime > 0) {
return `${betweenTime}${value.time} 전`;
}
}
// 모든 단위가 맞지 않을 시
return "방금 전";
경과시간에 밀리초 값을 나눠서 비교 값을 구해줄 수 있습니다. 해당 단위 밀리초 값보다 경과시간이 적을 시, 0보다 작은 소수점 값이 나오게 됩니다. ( 1분 / 1년 ) => 0.0000019...
구해준 값이 0보다 작을 시, 다음 작은 단위로 넘어가서 다시 비교해주고 정수 값이 나오게 되면, 구한 비교 값에 시간 명칭을 붙여서 반환해줍니다. 마지막 분단위에서도 결과가 나오지 않는다면 더 이상 비교가 불가능하다고 판단하고 "방금 전"이라는 문자를 반환해줍니다.
Intl.RelativeTimeFormat 사용하기
function elapsedTime(date) {
const start = new Date(date);
const end = new Date();
const diff = (end - start) / 1000;
const formatter = new Intl.RelativeTimeFormat('ko', {
numeric: 'auto',
});
const times = [
{ name: 'year', milliSeconds: 60 * 60 * 24 * 365 },
{ name: 'month', milliSeconds: 60 * 60 * 24 * 30 },
{ name: 'day', milliSeconds: 60 * 60 * 24 },
{ name: 'hour', milliSeconds: 60 * 60 },
{ name: 'minute', milliSeconds: 60 },
];
for (const value of times) {
const betweenTime = Math.floor(diff / value.milliSeconds);
if (betweenTime > 0) {
return formatter.format(betweenTime, value.name);
}
}
return '방금 전';
}
elapsedTime('2022-11-15');
Intl.RelativeTimeFormat 객체를 사용해서 현재 시간 기준으로 얼마나 시간이 지났는지 혹은 얼마나 걸릴 것인지 국제화해주는 형식입니다.
formatter.format(1, 'day')
// '내일'
formatter.format(-1, 'day')
// '어제'
formatter.format(0, 'day')
// '오늘'
formatter.format(60, 'day')
// '60일 후'
다음과 같이 '1일 전', '2일 전'과 같이 형식이 아닌 최대한 문자를 사용해서 '오늘', '어제'와 같은 형식을 받을 수 있습니다.
참고자료