[EXT-019][실무] 지난 시간과 남은 시간을 자연스럽게 표시하기 > IT 기술 공유

본문 바로가기
사이트 내 전체검색

IT 기술 공유

[EXT-019][실무] 지난 시간과 남은 시간을 자연스럽게 표시하기

페이지 정보

profile_image
작성자 기술팀장
댓글 0건 조회 20회 작성일 26-09-08 09:35

본문

[이번 수업]

알림 시각을 ‘어제’, ‘3일 전’, ‘2시간 후’라고 표시하면 현재와의 관계를 빨리 이해할 수 있습니다. 이번에는 상대 시간 형식화(relative time formatting, 기준보다 전인지 후인지 언어에 맞게 표현하는 기능)를 Intl.RelativeTimeFormat으로 구현합니다.

[선수지식]

JavaScript 객체와 Node.js 실행 방법을 알아야 합니다. 시간대와 절대 시각은 EXT-001, 복수 규칙은 EXT-017에서 먼저 확인하면 좋습니다.

[학습목표]

1. 상대 값의 음수·0·양수 의미를 설명한다.
2. numeric의 auto와 always 차이를 구분한다.
3. 시간 차이 계산과 문구 형식화를 분리한다.

[핵심개념]

Intl.RelativeTimeFormat의 format은 값과 단위를 받습니다. 음수는 과거, 양수는 미래, 0은 현재 방향입니다. 단위는 year, quarter, month, week, day, hour, minute, second 등을 사용할 수 있습니다. numeric: "always"는 가능한 한 ‘1일 전’처럼 숫자로 표시합니다. numeric: "auto"는 로케일 데이터에 알맞은 문구가 있으면 ‘어제’, ‘오늘’, ‘내일’, ‘지금’처럼 자연스러운 표현을 선택할 수 있습니다.

이 API는 두 날짜의 차이를 계산하거나 day와 hour 중 적합한 단위를 골라 주지 않습니다. 프로그램이 먼저 기준 시점, 시간대, 반올림 규칙, 단위를 결정한 다음 결과만 형식기에 전달해야 합니다. 달력에서 어제인 것과 정확히 24시간 전인 것은 일광절약시간 전환이나 시간대에 따라 다를 수 있습니다. 업무 규칙이 달력 날짜 기준인지 경과 시간 기준인지 먼저 정하세요.

[따라하기]

relative_time.js 파일에 다음 코드를 저장합니다.

```javascript
const natural = new Intl.RelativeTimeFormat("ko-KR", {
  numeric: "auto",
  style: "long",
});
const numeric = new Intl.RelativeTimeFormat("ko-KR", {
  numeric: "always",
  style: "long",
});

console.log(natural.format(-1, "day"));
console.log(numeric.format(-1, "day"));
console.log(natural.format(2, "hour"));
console.log(natural.format(0, "second"));

const parts = numeric.formatToParts(-3, "day");
console.log(parts.map(({ type, value }) => `${type}:${value}`).join("|"));
```

Windows PowerShell·명령 프롬프트, macOS 터미널, Linux 셸에서 같은 명령을 실행합니다.

```text
node relative_time.js
```

확인한 실행 환경의 결과입니다.

```text
어제
1일 전
2시간 후
지금
integer:3|literal:일 전
```

formatToParts는 숫자와 연결 문구를 나누므로 숫자만 별도 스타일로 표시할 때 유용합니다. Node.js의 Intl은 ICU와 CLDR 데이터를 사용하므로 데이터 버전에 따라 일부 문구나 공백이 달라질 수 있습니다. 운영과 테스트에서 같은 지원 버전을 쓰고 로케일·옵션을 명시하세요.

[흔한 실수]

첫째, 과거 값을 양수로 넣어 ‘후’라고 표시합니다. 둘째, 밀리초 차이를 계산해 놓고 day 단위 값처럼 전달합니다. 셋째, 23시간 전이면 무조건 어제라고 판단해 달력 기준과 경과 시간 기준을 섞습니다. 넷째, 몇 초마다 화면을 갱신하지 않아 문구가 오래된 상태로 남습니다. 다섯째, ‘어제’ 같은 자연어 문구를 다시 파싱해 원래 시각을 복원하려 합니다. 원본 타임스탬프를 따로 보관하세요.

[보안 주의]

상대 시간은 화면 설명일 뿐 인증 토큰 만료, 결제 기한, 잠금 해제 시각의 권위 있는 판단값이 아닙니다. 보안과 업무 마감은 서버의 검증된 절대 시각으로 판정하세요. 외부에서 받은 값은 유한한 숫자인지 확인하고 단위와 로케일은 허용 목록으로 제한합니다. 비정상적으로 큰 값은 화면과 로그를 어지럽힐 수 있으므로 범위도 정하세요. 출력에 사용자 문자열을 함께 넣는다면 HTML 문맥에 맞게 이스케이프합니다. 실습은 본인 소유의 로컬 파일에서만 진행합니다.

[직접 해볼 과제]

-2주, 0일, 5분 후를 auto와 always로 각각 표시해 차이를 기록하세요. 그런 다음 -90분을 그대로 minute로 표시한 결과와 반올림해 hour로 바꾼 결과를 비교하고, 제품에서 사용할 단위 전환 기준을 한 문장으로 정의하세요.

[확인문제]

1. RelativeTimeFormat에 전달하는 음수와 양수는 각각 무엇을 뜻하나요?
2. numeric: "auto"와 "always"는 어떻게 다른가요?
3. 상대 시간 문구를 인증 만료 판단에 사용하면 안 되는 이유는 무엇인가요?

[다음 학습]

다음에는 길이·용량·속도 같은 측정값을 로케일에 맞는 단위 문구로 표시합니다.

[공식 참고 자료]

ECMA-402 RelativeTimeFormat 객체
https://tc39.es/ecma402/#relativetimeformat-objects

Unicode LDML 상대 날짜·시간 필드
https://www.unicode.org/reports/tr35/tr35-dates.html#Calendar_Fields

Unicode CLDR 상대 날짜·시간 안내
https://cldr.unicode.org/translation/date-time/date-time-names

Unicode CLDR 안정 릴리스 안내
https://cldr.unicode.org/index/downloads

Node.js 국제화 지원과 ICU
https://nodejs.org/api/intl.html

댓글목록

등록된 댓글이 없습니다.

회원로그인

회원가입

사이트 정보

회사명 : 회사명 / 대표 : 대표자명
주소 : OO도 OO시 OO구 OO동 123-45
사업자 등록번호 : 123-45-67890
전화 : 02-123-4567 팩스 : 02-123-4568
통신판매업신고번호 : 제 OO구 - 123호
개인정보관리책임자 : 정보책임자명

접속자집계

오늘
937
어제
5,103
최대
16,772
전체
771,991
Copyright © 소유하신 도메인. All rights reserved.