[EXT-015][실무] 언어와 지역에 맞게 숫자 표시하기
페이지 정보
작성자 기술팀장 작성일 26-09-08 05:41 조회 13 댓글 0본문
[이번 수업]
같은 수 1234567.89도 한국에서는 1,234,567.89, 독일에서는 1.234.567,89처럼 보일 수 있습니다. 이번 수업에서는 로케일(locale, 언어·지역에 따른 표시 규칙)과 Intl.NumberFormat으로 숫자와 백분율을 읽기 쉽게 표시합니다. 계산용 값과 화면용 문자열을 분리하는 습관도 익힙니다.
[선수지식]
JavaScript 파일을 만들고 Node.js로 실행할 수 있어야 합니다. 소수 계산의 한계는 EXT-002에서 먼저 확인하면 좋습니다.
[학습목표]
1. BCP 47 언어 태그가 무엇인지 설명한다.
2. 숫자·백분율을 로케일에 맞게 형식화한다.
3. 형식화, 계산, 통화 환산, 입력 해석의 차이를 구분한다.
[핵심개념]
ko-KR, de-DE 같은 값은 BCP 47 형식의 언어 태그입니다. 앞부분은 언어, 뒤의 선택적 부분은 지역 등을 좁혀 줍니다. Intl.NumberFormat은 이 태그와 옵션을 받아 그룹 구분 기호, 소수점 기호, 백분율 표시 같은 화면 문자열을 만듭니다. 실제 표시 규칙은 실행 환경의 ICU와 CLDR 로케일 데이터에 영향을 받습니다.
중요한 경계가 있습니다. 형식화는 숫자의 의미를 바꾸는 계산이 아니며, KRW를 EUR로 환산하지도 않습니다. 또한 Intl.NumberFormat은 출력 도구이지 범용 숫자 입력 파서가 아닙니다. API와 데이터베이스에는 1234567.89처럼 로케일과 무관한 정규 값을 보관하고, 사용자에게 보여 주는 마지막 단계에서 형식화하세요. 금액이라면 값과 ISO 통화 코드를 함께 보관해야 합니다.
[따라하기]
locale_number.js 파일을 만들고 다음 코드를 저장합니다.
```javascript
const amount = 1234567.89;
const korean = new Intl.NumberFormat("ko-KR");
const german = new Intl.NumberFormat("de-DE");
const percent = new Intl.NumberFormat("ko-KR", {
style: "percent",
minimumFractionDigits: 1,
});
console.log("한국:", korean.format(amount));
console.log("독일:", german.format(amount));
console.log("비율:", percent.format(0.256));
const parts = german.formatToParts(amount);
console.log(parts.map(({ type, value }) => `${type}:${value}`).join("|"));
```
Windows PowerShell·명령 프롬프트, macOS 터미널, Linux 셸에서 모두 같은 명령을 실행합니다.
```text
node locale_number.js
```
확인한 실행 환경에서는 다음 결과가 나옵니다.
```text
한국: 1,234,567.89
독일: 1.234.567,89
비율: 25.6%
integer:1|group:.|integer:234|group:.|integer:567|decimal:,|fraction:89
```
formatToParts는 결과를 integer, group, decimal처럼 의미 있는 조각으로 나눕니다. 단순히 쉼표 위치를 찾는 것보다 안전하게 화면 요소를 꾸밀 수 있습니다. Node.js에 포함된 ICU/CLDR 버전 차이 때문에 공백 문자나 일부 통화 표기가 달라질 수 있습니다. 지원 중인 Node.js 실행 환경을 고정하고, 문자열 테스트도 같은 런타임에서 실행하세요.
[흔한 실수]
첫째, 모든 지역이 쉼표로 천 단위를 나눈다고 가정합니다. 구분 기호와 묶음 크기는 로케일마다 다를 수 있습니다. 둘째, 표시 문자열에서 쉼표만 지운 뒤 숫자로 믿습니다. 점이 소수점인지 그룹 기호인지 모호해질 수 있습니다. 셋째, 통화는 항상 소수 둘째 자리라고 고정합니다. 기본 소수 자릿수는 통화 데이터나 명시한 옵션에 따라 달라질 수 있습니다. 넷째, 스냅샷 테스트가 런타임 데이터 갱신 때문에 바뀔 가능성을 무시합니다.
[보안 주의]
금액·수량의 권위 있는 값은 서버에서 정규 형식으로 검증하세요. 사용자 로케일은 표시 선호일 뿐 권한이나 통화의 근거가 아닙니다. 주문 확인 화면에는 통화 코드와 최종 금액을 명확히 다시 보여 주고, 로그에는 기계가 비교 가능한 원본 값도 남기세요. 외부 문자열을 HTML에 넣을 때는 숫자 형식화와 별개로 출력 이스케이프가 필요합니다. 실습은 본인 소유의 로컬 파일에서만 진행합니다.
[직접 해볼 과제]
fr-FR 형식기를 추가해 같은 금액의 구분 기호를 비교하세요. 0.075를 소수점 한 자리 백분율로 표시한 뒤 formatToParts 결과도 출력합니다. 마지막으로 API에 보낼 값과 화면에 보여 줄 값을 각각 한 줄로 적어 왜 달라야 하는지 설명해 보세요.
[확인문제]
1. ko-KR 같은 언어 태그는 어떤 정보를 나타내나요?
2. Intl.NumberFormat 결과를 그대로 데이터베이스의 계산용 값으로 저장하면 왜 위험한가요?
3. formatToParts는 단순 문자열 치환보다 어떤 점에서 유용한가요?
[다음 학습]
다음에는 BCP 47 언어 태그와 사용자 설정의 우선순위를 이용해 애플리케이션의 표시 언어를 결정하는 방법을 학습합니다.
[공식 참고 자료]
ECMA-402 NumberFormat 객체
https://tc39.es/ecma402/#numberformat-objects
Unicode LDML 숫자 형식
https://www.unicode.org/reports/tr35/tr35-numbers.html
Unicode CLDR
https://cldr.unicode.org/
IETF BCP 47 언어 태그(RFC 5646)
https://www.rfc-editor.org/rfc/rfc5646.html
Node.js 국제화 지원과 ICU
https://nodejs.org/api/intl.html
같은 수 1234567.89도 한국에서는 1,234,567.89, 독일에서는 1.234.567,89처럼 보일 수 있습니다. 이번 수업에서는 로케일(locale, 언어·지역에 따른 표시 규칙)과 Intl.NumberFormat으로 숫자와 백분율을 읽기 쉽게 표시합니다. 계산용 값과 화면용 문자열을 분리하는 습관도 익힙니다.
[선수지식]
JavaScript 파일을 만들고 Node.js로 실행할 수 있어야 합니다. 소수 계산의 한계는 EXT-002에서 먼저 확인하면 좋습니다.
[학습목표]
1. BCP 47 언어 태그가 무엇인지 설명한다.
2. 숫자·백분율을 로케일에 맞게 형식화한다.
3. 형식화, 계산, 통화 환산, 입력 해석의 차이를 구분한다.
[핵심개념]
ko-KR, de-DE 같은 값은 BCP 47 형식의 언어 태그입니다. 앞부분은 언어, 뒤의 선택적 부분은 지역 등을 좁혀 줍니다. Intl.NumberFormat은 이 태그와 옵션을 받아 그룹 구분 기호, 소수점 기호, 백분율 표시 같은 화면 문자열을 만듭니다. 실제 표시 규칙은 실행 환경의 ICU와 CLDR 로케일 데이터에 영향을 받습니다.
중요한 경계가 있습니다. 형식화는 숫자의 의미를 바꾸는 계산이 아니며, KRW를 EUR로 환산하지도 않습니다. 또한 Intl.NumberFormat은 출력 도구이지 범용 숫자 입력 파서가 아닙니다. API와 데이터베이스에는 1234567.89처럼 로케일과 무관한 정규 값을 보관하고, 사용자에게 보여 주는 마지막 단계에서 형식화하세요. 금액이라면 값과 ISO 통화 코드를 함께 보관해야 합니다.
[따라하기]
locale_number.js 파일을 만들고 다음 코드를 저장합니다.
```javascript
const amount = 1234567.89;
const korean = new Intl.NumberFormat("ko-KR");
const german = new Intl.NumberFormat("de-DE");
const percent = new Intl.NumberFormat("ko-KR", {
style: "percent",
minimumFractionDigits: 1,
});
console.log("한국:", korean.format(amount));
console.log("독일:", german.format(amount));
console.log("비율:", percent.format(0.256));
const parts = german.formatToParts(amount);
console.log(parts.map(({ type, value }) => `${type}:${value}`).join("|"));
```
Windows PowerShell·명령 프롬프트, macOS 터미널, Linux 셸에서 모두 같은 명령을 실행합니다.
```text
node locale_number.js
```
확인한 실행 환경에서는 다음 결과가 나옵니다.
```text
한국: 1,234,567.89
독일: 1.234.567,89
비율: 25.6%
integer:1|group:.|integer:234|group:.|integer:567|decimal:,|fraction:89
```
formatToParts는 결과를 integer, group, decimal처럼 의미 있는 조각으로 나눕니다. 단순히 쉼표 위치를 찾는 것보다 안전하게 화면 요소를 꾸밀 수 있습니다. Node.js에 포함된 ICU/CLDR 버전 차이 때문에 공백 문자나 일부 통화 표기가 달라질 수 있습니다. 지원 중인 Node.js 실행 환경을 고정하고, 문자열 테스트도 같은 런타임에서 실행하세요.
[흔한 실수]
첫째, 모든 지역이 쉼표로 천 단위를 나눈다고 가정합니다. 구분 기호와 묶음 크기는 로케일마다 다를 수 있습니다. 둘째, 표시 문자열에서 쉼표만 지운 뒤 숫자로 믿습니다. 점이 소수점인지 그룹 기호인지 모호해질 수 있습니다. 셋째, 통화는 항상 소수 둘째 자리라고 고정합니다. 기본 소수 자릿수는 통화 데이터나 명시한 옵션에 따라 달라질 수 있습니다. 넷째, 스냅샷 테스트가 런타임 데이터 갱신 때문에 바뀔 가능성을 무시합니다.
[보안 주의]
금액·수량의 권위 있는 값은 서버에서 정규 형식으로 검증하세요. 사용자 로케일은 표시 선호일 뿐 권한이나 통화의 근거가 아닙니다. 주문 확인 화면에는 통화 코드와 최종 금액을 명확히 다시 보여 주고, 로그에는 기계가 비교 가능한 원본 값도 남기세요. 외부 문자열을 HTML에 넣을 때는 숫자 형식화와 별개로 출력 이스케이프가 필요합니다. 실습은 본인 소유의 로컬 파일에서만 진행합니다.
[직접 해볼 과제]
fr-FR 형식기를 추가해 같은 금액의 구분 기호를 비교하세요. 0.075를 소수점 한 자리 백분율로 표시한 뒤 formatToParts 결과도 출력합니다. 마지막으로 API에 보낼 값과 화면에 보여 줄 값을 각각 한 줄로 적어 왜 달라야 하는지 설명해 보세요.
[확인문제]
1. ko-KR 같은 언어 태그는 어떤 정보를 나타내나요?
2. Intl.NumberFormat 결과를 그대로 데이터베이스의 계산용 값으로 저장하면 왜 위험한가요?
3. formatToParts는 단순 문자열 치환보다 어떤 점에서 유용한가요?
[다음 학습]
다음에는 BCP 47 언어 태그와 사용자 설정의 우선순위를 이용해 애플리케이션의 표시 언어를 결정하는 방법을 학습합니다.
[공식 참고 자료]
ECMA-402 NumberFormat 객체
https://tc39.es/ecma402/#numberformat-objects
Unicode LDML 숫자 형식
https://www.unicode.org/reports/tr35/tr35-numbers.html
Unicode CLDR
https://cldr.unicode.org/
IETF BCP 47 언어 태그(RFC 5646)
https://www.rfc-editor.org/rfc/rfc5646.html
Node.js 국제화 지원과 ICU
https://nodejs.org/api/intl.html
댓글목록 0
등록된 댓글이 없습니다.
