🏃♂️ 들어가기 앞서..
본 게시물은 스터디 활동 중에 작성한 게시물로 자바의 정석-기초편 교재를 학습하여 정리하는 글입니다.
※ 스터디 Page : 〔투 비 마스터 : 자바〕
*해당 교재의 목차 순서와 구성을 참고하여 작성하며
각 내용마다 부족할 수 있는 내용이나 개인적으로 궁금한 점은
추가적인 검색을 통해 채워나갈 예정입니다.
날짜와 시간을 다룬 클래스는 과거부터 다양하게 존재해오고 있다.
초기에는
Date
클래스를 제공했지만
매우 빈약했고
이후,
새로운 Calendar
클래스가 제공되었지만
몇 가지 단점들이 있었다.
( 두 클래스 모두 java.util
패키지 )
현재는
java.time
패키지를 제공하며
기존 단점들을 개선한 클래스들을 사용할 수 있는데
여전히 이전 클래스들을 사용하고 있기 때문에
Calendar
클래스와 Date
클래스에 대해
알 필요가 있다.
(아쉽게도 java.time
패키지에 대한 내용은 「자바의 정석-3판」에서 다룬다고 한다..)
Calendar
클래스이 Calendar
클래스는
" 추상 클래스 "로
직접 객체를 생성하지 못해서
" getInstance()
메서드 "를 통해
완전히 구현된 클래스의 인스턴스를 얻어야 한다.
Calendar cal = new Calendar(); // 에러발생
Calendar cal = Calendar.getInstance();
Calendar 클래스에는 다양한 버전의 달력이 구성되어 있다.
- 서양력 :
GregorianCalendar
- 불교력 :
BuddhistCalendar
- 일본력
Calendar.getInstance()
메서드는
사용자의 시스템 정보를 읽어와
자동으로 적합한 달력 정보를 가지고 오는데
특정 역법 객체를 생성하도록 되어있으면
(ex.new GregorianCalendar();
과 같은 객체 생성 으로 프로그램을 작성 )다른 역법을 사용해야할 때,
클래스 전체적으로 수정이 필요하지만메서드로 작성하면
메서드의 내용만 변경하면 되기 때문에
유지보수가 편리하다.
get
메서드getInstance()
를 통해 인스턴스를 생성하게 되면
기본적으로
" 현재 시스템의 날짜와 시간 정보가 담겨있다. "
정보를 가져올 때 get()
메서드를 사용할 수 있는데
형식은
int get( int field )
이다.
매개변수로 field
값이 들어가게 된다.
◎ 날짜 필드
필드명 설명 YEAR
년 MONTH
월 ( 0부터 ) WEEK_OF_YEAR
그 해의 몇 번째 주 WEEK_OF_MONTH
그 달의 몇 번째 주 DATE
일 DAY_OF_MONTH
그 달의 몇 번째 일 DAY_OF_YEAR
그 해의 몇 번째 일 DAY_OF_WEEK
요일( 1 ~ 7 _ 1 : 일요일 ) DAY_OF_WEEK_IN_MONTH
그 달의 몇 번째 요일
◎ 시간 필드
필드명 설명 HOUR
시간( 0~11 ) HOUR_OF_DAY
시간( 0~23 ) MINUTE
분 SECOND
초 MILLISECOND
1/1000 초 ZONE_OFFSET
GMT 기준 시차 ( -12 ~ 12 ) AM_PM
오전 / 오후 (※ 추가적인 field는 Java API 문서 참고)
* getActualMaximum( Calendar.DATE )
: 이 달의 마지막 일
set
메서드get은 현재 사용자 시스템 정보를 불러온다면
set
은
날짜와 시간을 원하는 값으로 변경할 수 있다.
set메서드는
여러가지 오버로딩되어 있다.
void set(int field, int value) // 해당 field를 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) // 초 까지
/* 날짜 지정하기 */
Calendar date1 = Calendar.getInstance() ;
date1.set(2021, 7, 15) ; // 2021년 8월 15일 : 월 0부터 시작인 점 주의
// date1.set(Calendar.YEAR, 2017) ;
// date1.set(Calendar.MONTH, 7) ;
// date1.set(Calendar.DATE, 15) ;
/* 시간 지정하기 */
Calendar time1 = Calendar.getInstance() ;
// 10시 20분 30초
time1.set(Calendar.HOUR_OF_DAY, 10) ;
time1.set(Calendar.MINUTE, 20) ;
time1.set(Calendar.SECOND, 30) ;
* getTimeInMillis()
: 해당 시간의 1/1000 초 단위 시간
▶ " 두 날짜간의 차이 " 를 구하는 경우,
【 (
(이후 날짜).getTimeInMillis()
-(이전 날짜).getTimeInMillis()
)/ 1000
】
( milli second 단위이기 때문에/1000
을 해서 second 단위로 변환 ): 초단위 값으로 차이를 구한 후, " 일(日) 단위 "로 변환 ( 24*60*60 )해서 사용해도 된다.
초단위 값에 대해
x시 y분 z초 형식으로 만들기 위해서는
" 큰 단위부터 '몫'과 '나머지'를 활용해서 연산 "하면 편리하다.
( 단계별 단위값 계산하는 문제 유형에서 활요할 수 있다 : ex. 돈을 500원, 100원, 50원 동전별로 분류 )import java.util.* ; ... .. final int[] TIME_UNIT = {3600, 60, 1}; // " 큰단위 "부터 _ 시 - 분 - 초 final String[] TIME_UNIT_NAME = {"시간" , "분" , "초"}; Calendar time1 = Calendar.getInstance(); Calendar time2 = Calendar.getInstance(); .. //각 Calendar객체 값 지정 .. long diff = Math.abs(time1.getTimeInMillis() - time2.getTimeInMillis()) / 1000 ; String tmp = ""; for(int i = 0; i < TIME_UNIT.length ; i++) { tmp += diff/TIME_UNIT[i] + UIME_UNIT_NAME[i] ; // x시간 - y분 - z초 순으로 diff %= TIME_UNIT[i] // 나머지 }
clear
메서드Calendar 객체 모든 필드 초기화
( EPOCH Time으로 : 1970년 1월 1일 00:00:00 )
Calendar dt = Calendar.getInstance() ; // 현재시간
System.out.println(new Date(dt.getTimeInMillis())) ; // Fri Feb 11 19:14:17 KST 2022
dt.clear() ; //초기화
System.out.println(new Date(dt.getTimeInMillis())) ; // Thu Jan 01 00:00:00 KST 1970
매개변수로
int field
를 받을 수 있기 때문에
특정 필드 초기화를 할 수도 있다.
Calendar dt = Calendar.getInstance() ; // 현재시간
System.out.println(new Date(dt.getTimeInMillis())) ; // Fri Feb 11 19:14:17 KST 2022
dt.clear(Calendar.SECOND) ; // 초 초기화
dt.clear(Calendar.MINUTE) ; // 분 초기화
dt.clear(Calendar.HOUR_OF_DAY) ; // 시간(0~23) 초기화
dt.clear(Calendar.HOUR) ; // 시간(0~11) 초기화
System.out.println(new Date(dt.getTimeInMillis())) ; // Fri Feb 11 00:00:00 KST 2022
set()
날짜 시간을 변경하기 전에
" 차이를 더 정확하게 구하기 위해선 "
clear()
메서드를 수행한 후,
작업하는 것이 좋다.
add
메서드특정 필드의 값을 증가 / 감소 시키는 메서드
( 다른 필드에 영향 O _ ex. "분을 증가시키다가 '시'가 넘어가는 경우", "일을 증가시키다가 '월'이 넘어가는 경우 등 )※ 형식 =
add( int field, int amount )
Calendar date = Calendar.getInstance() ;
date.clear();
date.set(2022, 1, 28) ; // 2022년 2월 28일
date.add(Calendar.DATE, 1) ; // 날짜에 1 더함 -> 3월 1일로 넘어가는 경우
// add는 다른필드에 영향을 주기 때문에 MONTH는 2로 변경
date.add(Calendar.MONTH, -2) ; // 월에서 2를 뺌 -> 1월 1일
// 최종 결과 : 2022년 1월 1일
* 음수도 사용 가능
roll
메서드특정 필드의 값을 증가 / 감소 시키는 메서드
( 다른 필드에 영향 X _ ex. 분을 증가시키다가 '시'가 넘어가도 '시' 변화 X, "일을 증가시키다가 '월'이 넘어가도 '월' 변화 X 등 )※ 형식 =
roll( int field, int amount )
Calendar date = Calendar.getInstance() ;
date.clear();
date.set(2022, 1, 28) ; // 2022년 2월 28일
date.roll(Calendar.DATE, 1) ; // 날짜에 1 더함 -> 3월 1일로 넘어가는 경우
// But, roll은 다른필드에 영향을 주지 않기 때문에 MONTH는 1로 유지
date.add(Calendar.MONTH, -2) ; // 월에서 2를 뺌 -> 2월 1일
// 최종 결과 : 2022년 12월 1일
< 예외 경우 >
일 필드가 " 말일 (end of month) "일 때,
" 월 필드가 바뀔 경우 "
일 필드에 영향이 미칠 수 있다.
( ex. 3월 31일에서 MONTH -1
하면 2월 28일 이 되는 경우 )
* 음수도 사용 가능
※
Date
-Calendar
변환
- 《
Calendar
▶Date
》Calendar cal = Calendar.getInstance(); ... Date d = new Date(cal.getTimeInMillis()) ; // " 1/1000 초단위 값 "으로 Date 인스턴스 생성
- 《
Date
▶Calendar
》Date d = new Date() ; ... Calendar cal = Calendar.getInstance(); cal.setTime(d) ; // "Calendar 인스턴스 생성 후 " → " setTime 메서드 "로 세팅