공부/Java

[Java-10] 날짜와 시간 & 형식화 - Calendar, 형식화 클래스

줭♪(´▽`) 2021. 3. 12. 15:13

1. 날짜와 시간

1) Calendar와 Date

- java.util의 클래스로 날짜와 시간을 다룰 목적으로 제공

- JDK 1.8부터 'java.time패키지'로 기존의 단점들을 개선한 새로운 클래스들이 추가됨

- 하지만 Calendar와 Date는 20년 넘게 사용되어 왔으므로 기능을 알아두면 좋음

 

 

2) Calendar클래스

- Calendar는 추상클래스이므로 직접 객체를 생성할 수 없음

- 메서드를 통해서 완전히 구현된 클래스의 인스턴스를 얻어야 함

Calendar cal = new Calendar();	// 에러! 인스턴스 생성 불가능

Calendar cal = Calendar.getInstance();

 

- GregorianCalendar : Calendar를 상속받은 완전한 클래스로, 태국을 제외한 나머지 국가에서 사용하는 그레고리력에 맞게 구현한 클래스임

Calendar cal = new GregorianCalendar();

 

3) Date와 Calendar간의 변환

- Calendar가 추가되면서 Date의 대부분의 메서드는 'deprecated'되었음

// 1. Calendar -> Date
Calendar cal = Calendar.getInstance();
Date d = new Date(cal.getTimeInMillis());	// Date(long date)
Date d2 = cal.getTime();

// 2. Date -> Calendar
Date d = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(d);

 

4) Calendar클래스의 메서드

- Calendar.getInstance()를 통해 얻은 인스턴스는 현재 시스템의 날짜와 시간에 대한 정보를 담고 있음

 

- set() : 원하는 날짜나 시간으로 설정할 수 있음

void set(int field, int value)
void set(int year, int month, int date)
void set(int year, int month, int date, int hourOfDay, int minute)
void set(int year, int month, int date, int hourOfDay, int minute, int second)

 

- get(int field) : 원하는 필드의 값을 얻어올 수 있음

// 현재 날짜와 시간을 담고 있는 인스턴스 today 생성
Calendar today = Calendar.getInstance();

today.get(Calendar.YEAR);	// 현재 연도를 가져옴
today.get(Calendar.MONTH);	// 현재 월을 가져옴
...

 

get(int field)에서 field는 Calendar에 정의된 static상수임


get(Calendar.________)

YEAR : 연도
MONTH : 월 (0~11, 0은 1월)
WEEK_OF_YEAR : 이 해의 몇 째 주
WEEK_OF_MONTH : 이 달의 몇 째 주
DATE : 이 달의 몇 일
DAY_OF_MONTH : 이 달의 몇 일
DAY_OF_YEAR : 이 해의 몇 일
DAY_OF_WEEK : 요일 (1~7, 1은 일요일)
DAY_OF_WEEK_IN_MONTH : 이 달의 몇 째 요일
AM_PM : 오전(0), 오후(1)
HOUR : 시간 (0~11)
HOUR_OF_DAY : 시간 (0~23)
MINUTE : 분 (0~59)
SECOND : 초 (0~59)
MILLISECOND : 1000분의 1초 (0~999)
ZONE_OFFSET : TimeZone

getActualMaximum(Calendar.DATE) : 이 달의 마지막 일

 

 

- 두 날짜간의 차이를 구하려면 두 날짜를 최소단위인 초단위로 변경한 후 차이를 구함

- getTimeInMills() : 1/1000초 단위로 값을 반환

Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();

long diff = Math.abs(c2.getTimeInMillis() - c1.getTimeInMillis()) / 1000;	// 초 단위

 

- add(int field, int amount) : 지정한 필드의 값을 원하는 만큼 증가 또는 감소시킴 (다른 필드에 영향을 미침)

- roll(int field, int amount) : 지정한 필드의 값을 원하는 만큼 증가 또는 감소시킴 (다른 필드에 영향을 미치지 않음)

// add - 다른 필드에 영향 O
Calendar c1 = Calendar.getInstance();
c1.set(2015, 11, 31);		// 2015-12-31
c1.add(Calendar.MONTH, 1);	// 2016-1-31

// roll - 다른 필드에 영향 X
Calendar c2 = Calendar.getInstance();
c2.set(2015, 11, 31);		// 2015-12-31
c2.roll(Calendar.MONTH, 1);	// 2015-1-31

// 단, day 필드가 말일일 때, month 필드를 변경하면 day 필드에 영향을 끼칠 수 있음
Calendar c3 = Calendar.getInstance();
c3.set(2015, 0, 31);		// 2015-1-31
c3.roll(Calendar.MONTH, 1);	// 2015-2-28

 

 

 

 


 

 

2. 형식화 클래스

- 자바에서는 숫자, 날짜, 텍스트 데이터를 일정한 형식에 맞게 표현할 수 있는 방법을 객체지향적으로 설계하여 표준화하였고, 'java.text' 패키지로 제공함

 

1) DecimalFormat

- 숫자 형식화

- 숫자 데이터를 정수, 부동소수점, 금액 등의 다양한 형식으로 표현 가능

- 반대로 일정한 형식의 텍스트 데이터를 숫자로 변환 가능

 

기호 의미 패턴 결과 (1234567.89)
0 10진수 (값이 없을 때는 0) 0
0.0
0000000000.0000
1234568
1234567.9
0001234567.8900
# 10진수 #
#.#
##########.####
1234568
1234567.9
1234567.89
. 소수점 #.# 1234567.9
- 음수부호 #.#-
-#.#
1234567.9-
-1234567.9
, 단위 구분자 #,###.##
#,####.##
1,234,567.89
123,4567.89
E 지수기호 #E0
0E0
##E0
00E0
...
.1E7
1E6
1.2E6
12E5
...
; 패턴구분자 #,###.##+;#,###.##- 1,234,567.89+ (양수일 때)
1,234.567.89-  (음수일 때)
% 퍼센트 #.#% 123456789%
\u2030 퍼밀(퍼센트 x 10) #.#\u2030 1234567890%
\u00A4 통화 \u00A4 #,### \ 1,234,568
' escape문자 '#'#,###
''#,###
#1,234,568
1,234,568

 

DecimalFormat df = new DecimalFormat("#,###.##");
try {
	Number num = df.parse("1,234,567.89");   
} catch(Exception e) { }

- parse(String source) : DecimalFormat의 조상인 NumberFormat에 정의된 메서드로, 기호와 문자가 포함된 문자열을 숫자로 쉽게 변환

 

2) SimpleDateFormat

- 날짜와 시간 형식화

- DateFormat을 상속받아 완전하게 구현한 클래스

 

기호 의미 보기
G 연대(BC, AD) AD
y 년도 2006
M 월(1~12 또는 1월~12월) 10 또는 10월, OCT
w 년의 몇 번째 주(1~53) 50
W 월의 몇 번째 주(1~5) 4
D 년의 몇 번째 일(1~366) 100
d 월의 몇 번째 일(1~31) 15
F 월의 몇 번째 요일(1~5) 1
E 요일
a 오전/오후(AM, PM) PM
H 시간(0~23) 20
k 시간(1~24) 13
K 시간(0~11) 10
h 시간(1~12) 11
m 분(0~59) 35
s 초(0~59) 55
S 천분의 일초(0~999) 253
z Time zone(General time zone) GMT+9:00
Z Time zone(RFC 822 time zone) +0900
' escape문자(특수문자 표현) 없음

 

- 원하는 형식으로 출력하기

① 출력형식의 패턴을 작성하여 SimpleDateFormat 인스턴스 생성

② Date인스턴스를 가지고 format(Date d)를 호출

Calendar cal = Calendar.getInstance();
cal.set(2021, 3, 12);

Date day = cal.getTime();	// Calendar를 Date로 변환

SimpleDateFormat sdf1, sdf2, sdf3;
sdf1 = new SimpleDateFormat("yyyy-MM-dd");				
sdf2 = new SimpleDateFormat("yy-MM-dd E요일");		  
sdf3 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss a");	

System.out.println(sdf1.format(day));	// 2021-03-12
System.out.println(sdf2.format(day));	// 21-03-12 금요일
System.out.println(sdf3.format(day));	// 2021-03-12 14:44:48 오후

 

- 원하는 형식으로 변환하기

① 입력받을 형식의 패턴을 작성하여 SimpleDateFormat 인스턴스 생성

parse(String source)를 사용하여 입력받은 문자열 source를 날짜 Date인스턴스로 변환

③ Date인스턴스를 가지고 format(Date d)를 호출

DateFormat df1 = new SimpleDateFormat("yyyy년 MM월 dd일");	// 입력형식
DateFormat df2 = new SimpleDateFormat("yyyy/MM/dd");		// 출력형식

try {
	Date d = df1.parse("2021년 03월 12일");
	System.out.println(df2.format(d));	// 2021/03/12
} catche(Exception e) {}

 

3) ChoiceFormat

- 특정 범위에 속하는 값을 문자열로 변환

- ChoiceFormat(범위의 경계값, 범위에 포함된 값을 치환할 값)

// limits(범위의 경계값)과 grades(범위에 포함된 값을 치환할 문자열)의 순서와 개수를 맞춰야 함
double[] limits = {60, 70, 80, 90};	// 낮은 값 -> 큰 값의 순서
String[] grades = {"D", "C", "B", "A"};

int[] scores = {100, 95, 88, 70, 52, 60, 75};

ChoiceFormat form = new ChoiceFormat(limits, grades);
for(int i = 0; i < scores.length; i++) {
	System.out.println(scores[i] + ": " + form.format(scores[i]));
}

// 결과
100 : A
95 : A
88 : B
70 : C
52 : D
60 : D
70 : C

 

- ChoiceFormat(패턴)

String pattern = "60#D|70#C|80<B|90#A";	// # : 포함, < : 미포함

int[] scores = {100, 91, 90, 80, 82, 60, 75};

ChoiceFormat form = new ChoiceFormat(pattern);
for(int i = 0; i < scores.length; i++) {
	System.out.println(scores[i] + ": " + form.format(scores[i]));
}

// 결과
100 : A
91 : A
90 : A
80 : C
82 : B
60 : D
70 : C

 

4) MessageFormat

- 데이터를 정해진 양식에 맞게 출력

String msg = "Name: {0} \nTel: {1} \nAge: {2} \nBirthday: {3}\n";

Object[] arguments = { "이자바", "02-123-1234", "24", "01-15" };

String result = MessageFormat.format(msg, arguments);
System.out.println(result);


// 결과
Name: 이자바
Tel: 02-123-1234
Age: 24
Birthday: 01-15

 

 

 

 

 

 

 

참고 - Java의 정석 3rd Edition (저자 : 남궁성, 출판 : 도우출판)