Programming/Java

Java 날짜와 시간을 나타내는 Calendar class

Jan92 2021. 10. 18. 22:22

[Java] 날짜와 시간을 나타내는 Calender class

 

날짜와 시간은 어떤 프로젝트에서든 뺄 수 없는 데이터입니다. 개발을 하며 앞으로 계속 사용될 날짜와 시간에 대해 정리하고 싶어서 공부한 내용을 정리합니다.

 

 

'Date class'는 JDK 1.0부터 제공된 클래스로 제공되는 기능이 부족하여 JDK1.1부터 'Calendar class'가 나오게 되었습니다.

현재는 기존 클래스들의 단점을 개선한 JDK 1.8부터 나온 java.time 패키지의 'LocalDate', 'LocalTime', 'LocalDateTime'가 많이 사용되는데요. Date와 Calendar 역시 아직까지 사용되는 부분이 있기 때문에 간단하게 먼저 정리하려고 합니다.

 

 

Calendar cal = new Calendar();           // 에러 발생

Calendar cal = Calender.getInstance();

 

먼저 Calendar 같은 경우는 추상클래스입니다. 때문에 'new' 키워드를 통한 직접적인 객체 생성이 불가능한데요.

대신 getInstance() 메서드를 통해 완전히 구현된 클래스의 인스턴스를 얻어야 합니다.

 

 

* Calender는 GregorianCalender와 BuddhistCalendar 두 가지가 있는데, getInstance()를 통해 시스템의 국가와 지역 설정을 확인하여 태국인 경우는 BuddhistCalender를 반환하고, 그 외에는 GregorianCalendar를 반환합니다.

 

 


 

 

// Calendar to Date
Calendar cal = Calendar.getInstance();
Date date = new Date(cal.getTimeInMillis());   // Date(long date)


// Date to Calendar
Date date = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(date);

 

Calendar를 Date로 변환하는 방법과 반대로 Date를 Calendar로 변환하는 방법입니다.

 

 


 

 

Calendar date1 = Calendar.getInstance();
Calendar date2 = Calendar.getInstance();

date1.set(2021, 10, 17);
date2.set(2021, Calendar.OCTOBER, 18);

 

Calendar의 날짜는 위 코드처럼 set 메서드를 통해 설정할 수 있습니다.

 

long difference = (date2.getTimeInMillis() - date1.getTimeInMillis()) / 1000;

 

시간의 차이는 getTimeInMillis() 메서드로 천분의 일초 단위로 변환하여 비교하고 싶은 두 값을 뺀 뒤 1000으로 나눠주면 해당하는 시간 차이(초 단위)가 반환됩니다.

 

 

* 시간상 전, 후를 알고 싶을 때는 'boolean after(Object when)', 'boolean before(Object when)' 메서드를 사용할 수 있습니다.

 

 


 

 

Calendar today = Calendar.getInstance();

today.get(Calendar.YEAR);            // 2021 (년)
today.get(Calendar.MONTH);           // 9 (월)
today.get(Calendar.DATE);            // 18 (일)
today.get(Calendar.HOUR);            // 10 (시)
today.get(Calendar.MINUTE);          // 15 (분)
today.get(Calendar.SECOND);          // 42 (초)
today.get(Calendar.DAY_OF_WEEK);     // 2 (요일)

 

또한 위 코드의 예시처럼 get 메서드를 통해 '년', '월', '일', '시', '분', '초', '요일' 값을 가져올 수 있고, 그 외에도 '이 달의 몇 일', '이 해의 몇 일', '오전 또는 오후', '이 달의 마지막 날' 등을 구할 수 있습니다. 

 

 

* 이때 주의할 점은 월의 경우 값의 범위가 0~11입니다. 즉, 1월일 때 값은 0, 2월일 때 값은 1 이 되기 때문에 가져온 값 + 1을 해야 실제 월과 일치합니다.

 

* 요일의 범위는 1~7으로 1의 값이 일요일을 나타내고, 2는 월요일을 나타냅니다.

 

 


 

Calendar date = Calendar.getInstance();
date.set(2021, 10, 18);

date.add(Calendar.MONTH, -6);    // 6달 전

date.roll(Calendar.DATE, 31);    // 31일 후

 

add 메서드를 사용하게 되면 지정한 필드의 값을 원하는 만큼 증가시키거나 감소시킬 수 있습니다.

roll 메서드 또한 지정한 필드의 값을 증가 또는 감소 시킬 수 있는데, add 메서드와의 차이점은 다른 필드에 영향을 미치지 않는다는 것입니다.

 

예를 들어 add 메서드는 날짜 필드의 값을 31 증가시키면 다음 달로 넘어가기 때문에 월에도 영향을 미치게 됩니다.

하지만 roll 같은 경우 같은 상황에서 월에 영향을 미치지 않고 일 값만 바뀌게 됩니다.

 

 

Calendar cal = Calendar.getInstance();

cal.set(2021, 1, 31);
cal.roll(Calendar.MONTH, 1);

 

하지만 다음과 같은 1월 31일의 상황에서 roll 메서드를 사용하여 월 값을 1 증가시킨다면 2월은 31일이 없기 때문에 2월 28일로 값이 나오게 됩니다. 이 같은 경우는 예외적으로 다른 필드에 영향을 미치게 됩니다.

 

 


 

참고자료

 

[도서] Java의 정석 - 남궁 성

 

 

 

Calendar (Java Platform SE 7 )

Adds or subtracts (up/down) a single unit of time on the given time field without changing larger fields. For example, to roll the current date up by one day, you can achieve it by calling: roll(Calendar.DATE, true). When rolling on the year or Calendar.YE

docs.oracle.com