코린이의 소소한 공부노트

캘린더 클래스 본문

Java

캘린더 클래스

무지맘 2022. 10. 12. 15:58

[날짜와 시간을 다루기 위한 도구]

1. java.util.Date 클래스

  - 날짜와 시간을 다룰 목적으로 만들어진 클래스

  - Date의 메서드는 대부분 deprecated(사용X)되었지만 여전히 쓰이는 것도 있다.

2. java.util.Calendar 클래스

  - Date 클래스를 개선한 새로운 클래스

  - 여전히 단점이 존재한다.

3. java.time 패키지

  - Date와 Calendar 클래스의 단점(날짜와 시간을 같이 다뤄야 함 등)을 개선한 새로운 클래스 제공

  - 날짜만 다룰 때는 LocalDate, 시간만 다룰 때는 LocalTime, 두 가지 모두 다룰 때는 LocalDateTime을 쓰면 된다.

 

[Calendar 클래스]

- 날짜와 시간을 다루는 추상 클래스

- getInstance() 메서드는 Calendar 클래스를 구현한 클래스의 인스턴스를 반환한다.

Calendar cal = new Calendar(); // 에러. 추상 클래스는 인스턴스를 생성X

Calendar cal = Calendar.getInstance(); // OK
// 사용자 시스템을 확인해서 서양력, 불교력, 일본력 등의 달력 중 어떤 것을 사용하는지 확인 후 반환

Calendar cal = new GregorianCalendar();
// 특정 달력을 정해두면 다른 달력을 써야할때마다 수정해야하지만
// getInstance()를 사용하는 쪽은 수정할 필요가 없다. -> 추상화

 

1. get()으로 날짜와 시간 필드 가져오기

Calendar cal = Calendar.getInstance(); // 현재 날짜, 시간 세팅
int thisYear = cal.get(Calendar.YEAR); // 연도 반환
int lastDayOfMonth = cal.getActualMaximum(Calendar.DATE); // 이 달의 마지막 날 반환

// 오늘은 2022년 10월 12일 수요일, 예시 프로그램 돌린 시간은 오후 12시 3분 51초
// thisYear = 2022
// lastDayOfMonth = 31

 

2. Calendar 클래스에 정의된 필드

Calendar today = Calendar.getInstance();
// today = 2022년 10월 12일 수요일 오후 12시 3분 51초

1) YEAR / MONTH / DATE

// 해당 날짜의 연도
System.out.println(today.get(Calendar.YEAR)); // 2022

// 해당 날짜의 월. 0이 1월, 11이 12월
System.out.println(today.get(Calendar.MONTH)); // 9 -> 10월
// 월이 배열로 되어있어서 0부터 시작

// 해당 날짜의 일
System.out.println(today.get(Calendar.DATE)); // 12

2) WEEK_OF_YEAR / WEEK_OF_MONTH

// 해당 연도의 몇 번째 주
System.out.println(today.get(Calendar.WEEK_OF_YEAR)); // 42

// 해당 월의 몇 번째 주
System.out.println(today.get(Calendar.WEEK_OF_MONTH)); // 3
// 2022년 10월은 1토 / 2일~8토 / 9일~16토 이므로 12일은 셋째주

3) DAY_OF_YEAR / DAY_OF_MONTH / DAY_OF_WEEK / DAY_OF_WEEK_IN_MONTH

// 해당 월의 몇 번째 일. DATE와 같음.
System.out.println(today.get(Calendar.DAY_OF_MONTH)); // 12

// 해당 연도의 몇 번째 일
System.out.println(today.get(Calendar.DAY_OF_YEAR)); // 285
// 10월 12일은 1월 1일을 기준으로 285번째 일

// 해당 주의 몇 번째 일. 요일. 1이 일요일, 7이 토요일
System.out.println(today.get(Calendar.DAY_OF_WEEK)); // 4

// 해당 월의 몇 번째 요일.
System.out.println(today.get(Calendar.DAY_OF_WEEK_IN_MONTH)); // 2
// 2022년 10월에서 2번째로 맞는 수요일이라 2

4) HOUR / HOUR_OF_DAY / MINUTE / SECOND

// 12시간 형식에서의 시간
System.out.println(today.get(Calendar.HOUR)); // 0

// 24시간 형식에서의 시간
System.out.println(today.get(Calendar.HOUR_OF_DAY)); // 12

// 분
System.out.println(today.get(Calendar.MINUTE)); // 3

// 초
System.out.println(today.get(Calendar.SECOND)); // 51

5) MILLISECOND / ZONE_OFFSET / AM_PM

// 천 분의 일초. 초 다음 단위
System.out.println(today.get(Calendar.MILLISECOND)); // 253

// GMT기준 시차(millisecond). 우리나라의 경우 GMT+9
// 천분의 1초를 시간으로 표시하기 위해 3600000으로 나눔.(1시간 = 3600초, 1초 = 1000millisecond)
System.out.println((today.get(Calendar.ZONE_OFFSET)/(60*60*1000))); // 9

// 오전은 0, 오후는 1
System.out.println(today.get(Calendar.AM_PM)); // 1

 

3. set()으로 원하는 날짜와 시간 지정하기

// 오버로딩된 여러 함수들 중 원하는 것을 사용하면 된다.

// 1) 특정 필드값을 바꾸고 싶을 때
void set(int field, int value)

// 2) 연월일을 바꾸고 싶을 때
void set(int year, int month, int date)

// 3) 연월일 시분을 바꾸고 싶을 때
void set(int year, int month, int date, int hourOfDay, int minute)

// 4) 연월일 시분초를 바꾸고 싶을 때
void set(int year, int month, int date, int hourOfDay, int minute, int second)

Calendar date = Calendar.getInstance(); // 현재 날짜, 시간 정보가 저장된다.
// 날짜를 2021년 12월 18일로 바꾸고 싶다면
// 첫 번째 방법: 하나하나 바꾼다.
date.set(Calendar.YEAR, 2021);
date.set(Calendar.MONTH, 11); // 월은 0부터 시작!!
date.set(Calendar.DATE, 18);
// 두 번째 방법: 한 번에 바꾼다.
date.set(2021, 11, 18);

// 시간을 바꾸고 싶을때는 1개씩 바꿔야 한다.
date.set(Calendar.HOUR_OF_DAY, 10);
date.set(Calendar.MINUTE, 50);
date.set(Calendar.SECOND, 11);

 

4. 두 날짜 간의 차이 계산하기

// 두 날짜를 초로 바꿔서 뺀 후 계산
// today = 2022년 10월 12일, date = 2021년 12월 18일
long difference = (today.getTimeInMillis() - date.getTimeInMillis())/1000;
System.out.println(difference); // 25747200(초)
System.out.println(difference/(24*60*60)); // 298(일)

// 시간도 마찬가지 방식으로 계산

 

5. clear()로 Calendar 객체의 필드 초기화

Calendar today = Calendar.getInstance(); // 현재 날짜, 시간 세팅
System.out.println(new Date(today.getTimeInMillis())); // Wed Oct 12 13:09:05 KST 2022

// 초기화 하는 방법1: 모든 필드 초기화
today.clear();
System.out.println(new Date(today.getTimeInMillis())); // Thu Jan 01 00:00:00 KST 1970

// 초기화 하는 방법2: 특정 필드만 골라서 초기화
today.clear(Calendar.SECOND); // 0초로 초기화
today.clear(Calendar.MINUTE); // 0분으로 초기화

 

6. add()로 특정 필드의 값을 증가(양수) 또는 감소(음수)

Calendar date = Calendar.getInstance();
date.clear();
date.set(2022, 7, 31);		// 2022년 8월 31일
date.add(Calendar.DATE, +1);	// 2022년 9월 1일
date.add(Calendar.MONTH, -10);	// 2021년 11월 1일

// 특정 필드 값의 변화가 다른 필드 값에도 영향을 미침

 

7. roll()로 특정 필드의 값을 증가(양수) 또는 감소(음수)

Calendar date = Calendar.getInstance();
date.clear();
date.set(2022, 7, 31);		// 2022년 8월 31일
date.roll(Calendar.DATE, +1);	// 2022년 8월 1일
date.roll(Calendar.MONTH, -10);	// 2022년 10월 1일

// 특정 필드 값의 변화가 다른 필드 값에 영향을 미치지 않음

 

8. 달력 만들기

// 1) 원하는 달 선택
int year  = 2022; 
int month = 10; 

// 2) 달력을 그리기 위한 초기 작업
Calendar start = Calendar.getInstance(); // 달력 시작 날짜 
start.set(year, month-1, 1); // 2022년 10월 1일
int START_DAY_OF_WEEK = start.get(Calendar.DAY_OF_WEEK); ; // 시작 요일 - 토요일
		
Calendar end = Calendar.getInstance(); // 달력 끝 날짜
end.set(year, month, 1); // 2022년 11월 1일
end.add(Calendar.DATE, -1); // 2022년 10월 31일
int END_DAY = end.get(Calendar.DATE); // 마지막 날짜 - 31

// 3) 달력 출력
System.out.println("        " + year +"년 " + month +"월"); 
System.out.println(" SUN MON TUE WED THU FRI SAT"); 

// 1일이 어떤 요일에 있냐에 따라 공백 반복 출력
for(int i=1 ; i<START_DAY_OF_WEEK ; i++)  
    System.out.print("    "); 
            
for(int i=1, n=START_DAY_OF_WEEK ; i<=END_DAY ; i++, n++) { 
    System.out.print((i < 10)? "   "+i : "  "+i ); 
    if(n%7==0) // 토요일마다 줄바꿈
        System.out.println();
    }

// 결과
        2022년 10월
 SUN MON TUE WED THU FRI SAT
                           1
   2   3   4   5   6   7   8
   9  10  11  12  13  14  15
  16  17  18  19  20  21  22
  23  24  25  26  27  28  29
  30  31

 

[Date와 Calendar간의 변환]

- Date의 메서드는 대부분 deprecated됐지만 여전히 사용하고 있다.

// 1. Calendar를 Date로 변환
Calendar cal = Calendar.getInstance();
//...
Date d = new Date(cal.getTimeInMillis()); // Date(long date)

// 2. Date를 Calendar로 변환
Date d = new Date();
//...
Calendar cal = Calendar.getInstance();
cal.setTime(d);

[쿠키글1] deprecated

현재는 사용할 수는 있으나 중요도가 점차 떨어지면서 추후 없어질 수 도 있다는 뜻으로, 이 기능이 없어질 것을 대비해 사용을 권장하지 않는다는 표현을 할 때 쓰는 말이다.

 

[쿠키글2] 날짜 차이 계산할 때 실제와 차이가 발생한다면?

앞서 두 날짜의 차이를 계산할 때 밀리세컨드 단위로 변환 후 그 차이를 구해서 날짜 계산을 했는데, 실제로는 7일 차인데 6일 차이로 나오는 경우도 있다. 이것은 연월일뿐만 아니라 시분초까지 계산에 넣다가 생기는 오차다. 시분초를 제외하고 날짜 차이를 구하려면 clear()를 이용해야 훨씬 깔끔하다.

// 객체 생성 후
Calendar d1 = Calendar.getInstance();
Calendar d2 = Calendar.getInstance();

// 초기화를 해준 다음
d1.clear();
d2.clear();

// 원하는 날짜를 세팅해준 후
d1.set(..);
d2.set(..);

// 차이를 계산해주는 것이 정확하다.
long difference = (today.getTimeInMillis() - date.getTimeInMillis())/1000;

 

'Java' 카테고리의 다른 글

컬렉션 프레임워크  (0) 2022.10.26
형식화 클래스  (0) 2022.10.21
문자열의 여러 가지 변환, 오토박싱, 언박싱  (0) 2022.10.11
래퍼 클래스, 넘버 클래스  (0) 2022.10.11
StringBuilder 클래스  (0) 2022.08.24