숫자, 날짜, 텍스트 데이터를 일정한 형식에 맞게 formatting 시켜주는 클래스
formatting을 위한 패턴을 정의하면 그 패턴에 맞게 데이터가 가공됨.
숫자를 formatting 하는데에 사용 (반대로, formatting된 데이터를 숫자로 변환도 가능)
DecimalFormat
의 인스턴스를 생성하고, 생성자 인자로 패턴을 넣으면 사용할 준비 완료 (패턴의 종류와 설명은 교재 p.541)
→ 정수, 부동소수점, 금액 등 다양한 형식
String format
()
DecimalFormat
의 인스턴스 메서드
매개변수 타입은 long
, double
, Object
등...
인자를 패턴에 맞게 formatting 해줌
DecimalFormat df = new DecimalFormat("#.#E0");
df.format(1234567.89); // 1.2E6
위 예시는 "#.#E0" 패턴을 사용했는데, 다음과 같은 의미를 지님
10진수(#) + 소수점(.) + 10진수(#) + 지수(E) + 10진수(0 = 값이 없을 경우에 0 처리)
Number parse
()
DecimalFormat
의 조상인 NumberForamt
의 인스턴스 메서드
String
또는 StringBuffer
타입의 문자열을 받아와 기호와 문자를 제거하고 숫자로 변환해줌
👨💻 특정 패턴으로 format 했다가 다시 parse 하여 원래의 값으로 돌아오는 예제
class FormatAndParseExample {
public static void main(String[] args) {
double num = 1234567.89;
DecimalFormat df = new DecimalFormat("#,###.##"); // 정수부는 3자리 단위로 쉼표를 넣고, 소수점 아래는 2자리까지 표현
String formattedNum = df.format(num);
System.out.println(formattedNum); // 1,234,567.89
try {
Number parsedNum = df.parse(formattedNum);
double result = parsedNum.doubleValue(); // parse를 한 결과가 Number 타입이므로 double로 변환해줌
System.out.println(result); // 1234567.89
} catch (ParseException e) {
System.out.println("parse failed.");
}
}
}
📌 [주의]
parse
()를 사용할 때는 반드시 예외처리를 해주어야함 (parse의 선언부에 예외가 선언되어 있음)public Number parse(String source) throws ParseException { ... }
Date
와 Calendar
클래스를 이용해서 얻을 수 있는 날짜 데이터를 좀 더 입맛에 맞게 formatting 시켜줌
생성자에 문자열로 된 패턴을 넣어 인스턴스를 생성해주고, format
메서드를 사용하면 됨.
📌 [주의]
format
메서드는Date
인스턴스를 가지고만 쓸 수 있기 때문에Calendar
를 사용한다면Date
로 변환해주어야함.
Date today = new Date();
System.out.println(today); // Wed Jan 26 18:06:56 KST 2022
SimpleDateFormat sdf = new SimpleDateFormat("yyyy년 MM월 dd일 E요일 HH:mm:ss", Locale.KOREA);
System.out.println(sdf.format(today)); // 2022년 01월 26일 수요일 18:06:56
생성자의 두번째 인자로 넣은
Locale.KOREA
는 기준 지역을 나타내는 상수(요일 같은 데이터가 한글로 나오게 하기 위해 넣음)
기호 | 의미 |
---|---|
G | 연대(BC, AD) |
y | 연도 |
M | 월(1 ~ 12) |
w | 연도의 몇번째 주(1 ~ 53) |
W | 월의 몇번째 주(1 ~ 5) |
D | 연도의 몇번째 일(1 ~ 366) |
d | 월의 몇번째 일(1 ~ 31) |
F | 월의 몇번째 요일(1 ~ 5) |
E | 요일 |
a | 오전/오후(AM, PM) |
H | 시간(0 ~ 23) |
k | 시간(1 ~ 24) |
K | 시간(0 ~ 11) |
h | 시간(1 ~ 12) |
m | 분(0 ~ 59) |
s | 초(0 ~ 59) |
S | 밀리초(0 ~ 999) |
z | GMT |
Z | RFC 822 time zone |
' | 이스케이프 문자 |
parse
메서드를 이용하면 문자열을 Date
인스턴스로 변환해줌.
Date today = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy년 MM월 dd일", Locale.KOREA);
String formatted = sdf.format(today);
System.out.println(formatted); // 2022년 01월 26일
try {
Date parsed = sdf.parse("2022년 01월 26일");
System.out.println(parsed); // Wed Jan 26 00:00:00 KST 2022
} catch (ParseException e) {
System.out.println("parse failed.");
}
사용자로부터 입력받은 날짜 문자열을 날짜로 인식하는데에 유용함
예시) 사용자로부터 날짜 텍스트 입력받아 Date 데이터로 인식하기
class SDFExample {
public static void main(String[] args) {
String pattern = "(\\d{4})-(\\d{2})-(\\d{2})";
String datePattern = "yyyy-MM-dd";
Scanner scanner = new Scanner(System.in);
SimpleDateFormat sdf = new SimpleDateFormat(datePattern);
Date d = null;
while (d == null) {
System.out.println("날짜를 yyyy-mm-dd 형태로 입력해주세요!");
String userInput = scanner.nextLine();
try {
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher(userInput);
if(!m.matches()) throw new Exception();
d = sdf.parse(userInput);
System.out.println(d + " 날짜 데이터가 정상 인식되었습니다.");
} catch (Exception e) {
System.out.println("잘못된 형식입니다.");
}
}
}
}
실행 결과)
날짜를 yyyy-mm-dd 형태로 입력해주세요!
hello
잘못된 형식입니다.
날짜를 yyyy-mm-dd 형태로 입력해주세요!
123-4-56
잘못된 형식입니다.
날짜를 yyyy-mm-dd 형태로 입력해주세요!
1996-10-28
Mon Oct 28 00:00:00 KST 1996 날짜 데이터가 정상 인식되었습니다.
지정된 범위에 속하는 값을 지정된 문자열로 변환해줌
ChoiceFormat
의 생성자는 2가지 버전이 있는데 하나는 문자열 패턴을 넘기는 방식, 다른 하나는 경계값과 치환값을 넘기는 방식임
문자열 패턴 지정
구간은 |
로 구분
#
은 경계값을 범위에 포함, <
은 미포함
예시)
class CFExample {
public static void main(String[] args) {
String pattern = "60#D|70#C|80#B|90#A|97<A+"; // 패턴
int[] scoreData = {95, 63, 78, 100, 84, 92, 69};
ChoiceFormat cf = new ChoiceFormat(pattern);
for (int i = 0; i < scoreData.length; i++) {
System.out.println(scoreData[i] + ": " + cf.format(scoreData[i]));
}
}
}
경계값과 치환값 지정
경계값은 double[]
, 치환값은 String[]
타입이어야함
경계값은 오름차순으로 정렬되어 있어야하며, 치환값의 개수는 경계값으로 정해진 구간의 개수와 동일해야함
예시)
class CFExample {
public static void main(String[] args) {
double[] limits = {60, 70, 80, 90, 98}; // 경계값
String[] grades = {"D", "C", "B", "A", "A+"}; // 치환값
int[] scoreData = {95, 63, 78, 100, 84, 92, 69};
ChoiceFormat cf = new ChoiceFormat(limits, grades);
for (int i = 0; i < scoreData.length; i++) {
System.out.println(scoreData[i] + ": " + cf.format(scoreData[i]));
}
}
}
실행 결과는 두 방법 모두 같음.
실행 결과)
95: A
63: D
78: C
100: A+
84: B
92: A
69: D
데이터를 정해진 양식에 맞게 출력할 수 있도록 도와줌
다양한 데이터에 대해 같은 양식을 사용하여 출력할 때 유용함
예시)
class MessageFormatExample {
public static void main(String[] args) {
String message = "Title: {0}\nDirector: {1}\nGenre: {2}\nRunning Time: {3}\nRelease Date: {4}";
Object[] arguments = {"The Dark Knight", "Christopher Nolan", "Action", "152 min", "2008-08-06"};
String result = MessageFormat.format(message, arguments);
System.out.println(result);
}
}
실행 결과)
Title: The Dark Knight
Director: Christopher Nolan
Genre: Action
Running Time: 152 min
Release Date: 2008-08-06
format
메서드의 첫번째 인자로 문자열을 작성할 때, 데이터가 들어가길 원하는 자리에 {인덱스(숫자)}
를 넣음
그 자리에 객체 배열의 원소인 각 데이터가 순서대로 들어가게됨.
미리 패턴을 제시해두고, 해당 패턴에 맞는 문자열을 대입하면 원하는 데이터를 추출해올 수 있음
예시)
class MessageFormatExample2 {
public static void main(String[] args) {
String[] data = {"NAME: Andy, POSITION: back-end, CONTACT: 010-1234-5678, EMAIL: andy@email.com", "NAME: Paul, POSITION: front-end, CONTACT: 010-8765-4321, EMAIL: paul@email.com", "NAME: Michael, POSITION: dev-ops, CONTACT: 010-1212-3434, EMAIL: michael@email.com"};
String pattern = "NAME: {0}, POSITION: {1}, CONTACT: {2}, EMAIL: {3}";
MessageFormat mf = new MessageFormat(pattern);
for (int i = 0; i < data.length; i++) {
try {
Object[] objArr = mf.parse(data[i]);
System.out.println(objArr[1]);
} catch (ParseException e) {
System.out.println("parse failed.");
}
}
}
}
실행 결과)
back-end
front-end
dev-ops
MessageFormat
의 생성자에 패턴 문자열을 넣어두고, parse
메서드에 패턴에 부합하는 문자열 데이터를 넘겼음
parse
메서드는 Object
배열에 지정된 위치의 데이터를 순서대로 담아 반환하기 때문에, 인덱싱을 통해 원하는 데이터를 추출하기 용이함.