개요

DecimalFormat은 미리 정의된 포맷을 사용하여 10진수 문자열 표현을 형식화 할 수 있는 NumberFormat 의 하위 클래스이다. 역으로 문자열을 숫자로 구문 분석하는 데 사용할 수도 있다. 이번 포스팅에서는 DecimalFormat 의 사용법을 알아본다.

패턴 문자

숫자를 어떤 형식으로 나타낼 지 지정하기 위해서는 먼저 패턴 문자를 알아야한다. 총 11가지 문자가 있지만, 네 가지만 알고 있으면 대부분의 상황에서 문제 없이 사용할 수 있다.

  • 0 : 값이 제공되면 숫자를, 그렇지 않다면 0을 출력
  • # : 값이 제공되면 숫자를, 그렇지 않다면 아무것도 출력하지 않음
  • . : 소수점 구분 기호를 넣을 위치를 지정
  • , : 그룹화 구분 기호를 넣을 위치를 지정

DecimalFormat 사용 시 패턴이 지정될 경우 지정된 규칙이 실행되고, 그렇지 않은 경우는 JVM LocaleDecimalFormatSymbol 에 따라 규칙이 실행된다.

기본 포맷팅

실제 코드를 통해 포맷을 적용해보자.

Simple Decimal

정수 부분은 패턴 문자가 입력되는 문자보다 개수가 더 적더라도 잘리지 않는다. 다음의 테스트 코드를 통해 확인할 수 있다.

double d = 123.45;
Assertions.assertEquals(new DecimalFormat("#.##").format(d), "123.45");
Assertions.assertEquals(new DecimalFormat("0.00").format(d), "123.45");

정수와 소수 부분의 패턴 문자가 입력되는 문자보다 길 경우는 # 인 경우 삭제되고, 0 인 경우는 0 이 채워지는 것을 볼 수 있다.

double d = 123.45;
assertEquals(new DecimalFormat("####.###").format(d), "123.45");
assertEquals(new DecimalFormat("0000.000").format(d), "0123.450");

Rounding (반올림)

앞에서 정수 부분은 패턴 문자가 입력되는 문자보다 개수가 더 적더라도 잘리지 않는다고 하였다. 하지만 소수 부분은 패턴 문자가 더 적은 경우, 패턴 문자의 길이에 맞게 반올림 된다.

double d = 123.45;
assertEquals(new DecimalFormat("#.#").format(d), "123.5");
assertEquals(new DecimalFormat("#").format(d), "123");

Grouping (그룹핑)

, 패턴 문자는 다음과 같이 사용한다.

double d = 1234567.89;
assertEquals(new DecimalFormat("#,###.#").format(d), "1,234,567.9");
assertEquals(new DecimalFormat("#,###").format(d), "1,234,568");

Mixing String Literals (문자열 리터럴 혼용)

문자열 리터럴과 패턴을 혼용하여 사용할 수 있다.

double d = 1234567.89;
assertEquals(new DecimalFormat("The # number").format(d), "The 1234568 number");

다음과 같은 방법을 통해 문자열 리터럴에 특수 문자를 사용 수도 있다.

double d = 1234567.89;
assertEquals(new DecimalFormat("The '#' # number").format(d), "The # 1234568 number");

Localized Formatting

이탈리아 같은 몇몇의 나라에서는 그룹핑 문자로 . 를 사용하고 소수 구분 기호로 , 를 사용한다. 이런 나라에서는 #,###.## 패턴을 이용할 시 1.234.567,89 로 포맷팅 된다. 경우에 따라 이는 유용한 i18n 기능이 될 수도 있지만, 그렇지 않은 경우도 있을 것이다. 이럴 때에는 DecimalFormatSymbols 을 사용한다.

double d = 1234567.89;
assertEquals(new DecimalFormat("#,###.##", new DecimalFormatSymbols(Locale.ENGLISH)).format(d), "1,234,567.89");
assertEquals(new DecimalFormat("#,###.##", new DecimalFormatSymbols(Locale.ITALIAN)).format(d), "1.234.567,89");

Parsing

다음과 같이 문자열을 숫자로 파싱이 가능하다.

assertEquals(new DecimalFormat("", new DecimalFormatSymbols(Locale.ENGLISH)).parse("1234567.89"), 1234567.89);

Thread-Safety

DecimalFormat 은 스레드에 안전하지 않기 때문에 스레드 간 동일 인스턴스를 공유할 때 주의하여야 한다.

참조

A Practical Guide to DecimalFormat