[프로그래머스 자바 중급] 날짜와 시간 : Calendar
자바에서의 날짜 및 시간 처리
- JDK 1.0에서는
Date
클래스를 사용하여 날짜에 관한 간단한 처리를 수행할 수 있었으나, 현재Date
클래스 대부분의 메소드는 사용을 권장하지 않고(deprecated) 있다. - JDK 1.1부터는 새롭게 제공되는
Calendar
클래스를 이용하여 날짜와 시간에 관한 처리를 수행.- 하지만,
Calendar
클래스는 다음과 같은 문제점이 있다.Calendar
인스턴스는 불변 객체(immutable object)가 아니라서 값이 수정될 수 있다.- 윤초(leap second)와 같은 특별한 상황을 고려하지 않는다.
- 월(month)을 나타낼 때, 1월부터 12월을 0부터 11까지로 표현해야 하는 불편함이 있다.
- 따라서, 더 나은 성능의 Joda-Time이라는 라이브러리를 함께 사용.
- Java SE 8 버전에서는 Joda-Time 라이브러리를 발전시킨 새로운 날짜와 시간 API인
java.time
패키지를 제공. java.time
패키지는 위와 같은 문제점을 모두 해결했으며, 다양한 기능을 지원하는 다수의 하위 패키지를 포함하고 있다.
- Java SE 8 버전에서는 Joda-Time 라이브러리를 발전시킨 새로운 날짜와 시간 API인
- 하지만,
java.util.Calendar 클래스
- 자바에서 날짜와 시간에 관한 데이터를 손쉽게 처리할 수 있도록 제공하는 추상 클래스.
- 추상 클래스로 선언된 이유는 나라마다 사용하는 달력 체계가 조금씩 다를 수 있기 때문이다.
- 날짜와 시간을 처리하기 위한 다양한 필드와 메소드가 포함되어 있다.
- 현재 날짜와 시간에 대한 정보를 가진다.
- 지역화에 대한 고려가 되어 있지 않다는
Date
의 단점을 보완하기 위해 등장 - 모든 필드는 클래스 변수(static variable)이므로, 인스턴스를 생성하지 않고도 바로 사용할 수 있다.
Calendar 클래스의 인스턴스 생성
Calendar
클래스는 추상 클래스이므로, 직접 인스턴스를 생성할 수 없다.-
Calendar
클래스가 가지고 있는 클래스 메소드getInstance()
를 사용해GregorianCalendar
클래스의 인스턴스를 생성하여 사용한다.Calendar cal = Calendar.getInstance();
getInstance()
메소드를 호출하면 내부적으로java.util.GregorianCalendar
인스턴스를 만들어 반환한다.- 시스템의 현재 날짜와 시간으로 인스턴스를 생성한다.
- GregorianCalendar 클래스
- 현재 전 세계적으로 많이 사용되는 달력으로, 1582년 교황 그레고리오 13세가 개혁한 그레고리오 달력.
- 추상 클래스인 Calendar 클래스를 상속받아, 그레고리오 달력을 완전히 구현한 하위 클래스.
add() 메소드
- 전달된
Calendar
필드에서 일정 시간 만큼을 더하거나 빼준다. -
즉, 특정 시간을 기준으로 일정 시간 전후의 날짜와 시간을 알 수 있다.
-
ex) 현재 시각에 120초를 더하기
Calendar time = Calendar.getInstance(); System.out.println(time.getTime()); // Thu Feb 16 08:57:29 KST 2017 time.add(Calendar.SECOND, 120); // 120초 증가 System.out.println(time.getTime()); // Thu Feb 16 08:59:29 KST 2017
before()와 after() 메소드
- 두 시간 사이의 전후 관계를 알고 싶을 때 사용.
before()
메소드는 현재Calendar
인스턴스가 전달된 객체가 나타내는 시간보다 앞서는지 판단.-
after()
메소드는 현재Calendar
인스턴스가 전달된 객체가 나타내는 시간보다 나중인지를 판단.// 현재 날짜와 시간 Calendar time1 = Calendar.getInstance(); Calendar time2 = Calendar.getInstance(); Calendar time3 = Calendar.getInstance(); // 날짜 설정 time2.set(1982, 2, 19); time3.set(2022, 2, 19); System.out.println(time1.before(time2)); // false, time1이 time2보다 앞서지 않는다. System.out.println(time1.before(time3)); // true, time1이 time3보다 앞선다.
get() 메소드
- 전달된
Calendar
필드에 저장된 값을 반환. -
메소드의 인자로 어떤 상수를 넣어주느냐에 따라 나오는 값이 다르다.
Calendar time = Calendar.getInstance(); System.out.println(time.getTime()); // Thu Feb 16 08:57:44 KST 2017 ----> 현재 날짜와 시간 System.out.println(time.get(Calendar.DAY_OF_WEEK)); // 5 ----> 목요일(1~7, 일~토) System.out.println(time.get(Calendar.MONTH) + 1); // 2 ----> 2월(0부터 시작) System.out.println(time.get(Calendar.DAY_OF_MONTH)); // 16 ----> 16일 System.out.println(time.get(Calendar.HOUR_OF_DAY)); // 8 ----> 8시(24시간제) System.out.println(time.get(Calendar.MINUTE)); // 57 ----> 57분 System.out.println(time.get(Calendar.SECOND)); // 44 ----> 44초 System.out.println(time.get(Calendar.YEAR)); // 2017 ----> 2017년
roll() 메소드
- 전달된
Calendar
필드에서 일정 시간 만큼을 더하거나 빼준다. - 하지만,
add()
메소드와 달리 다른 Calendar 필드에는 영향을 주지 않는다. - 즉, 계산 결과가 해당 필드의 최댓값이나 최솟값을 넘어가도 다른 필드에 영향을 주지 않는다.
- 예를 들어
add()
메소드로 날짜 필드(Calendar.DATE)의 값을 31만큼 증가시켰다면, 다음 달로 넘어가므로 월 필드(Calendar.MONTH)의 값도 1증가하지만,roll()
메소드는 월 필드의 값은 변하지 않고 일 필드의 값만 변한다. - 단, 한 가지 예외가 있는데 일 필드(Calendar.DATE)가 말일(end of month)일 때,
roll()
메소드를 이용해서 월 필드(Calendar.MONTH)를 변경하는 경우, 일 필드에게 영향을 미칠 수 있다.
Calendar time1 = Calendar.getInstance(); Calendar time2 = Calendar.getInstance(); System.out.println(time1.getTime()); // Thu Feb 16 08:58:23 KST 2017 time1.add(Calendar.SECOND, 60); // 60초(1분) 증가 System.out.println(time1.getTime()); // Thu Feb 16 08:59:23 KST 2017 time2.roll(Calendar.SECOND, 60); // 60초(1분) 증가 System.out.println(time2.getTime()); // Thu Feb 16 08:58:23 KST 2017 -> 분 필드에 영향 X
add()
메소드를 사용하여Calendar.SECOND
필드를 60초 증가시키면, 결과적으로Calendar.MINUTE
필드가 1 증가한다.- 하지만,
roll()
메소드를 사용하여Calendar.SECOND
필드를 60초 증가시키면,Calendar.MINUTE
필드에는 아무런 영향을 주지 않는다.- 즉, Calendar.SECOND 필드만이 60초 증가하여 결과적으로 같은 값이 출력된다.
- 예를 들어
set() 메소드
-
Calendar 인스턴스의 필드를 특정 값으로 설정.
-
ex)
set()
메소드에 다양한 형태의 인수를 전달하여 시간을 설정// 현재 날짜와 시간 Calendar time = Calendar.getInstance(); System.out.println(time.getTime()); // Thu Feb 16 08:58:01 KST 2017 // 연도 설정 time.set(Calendar.YEAR, 2020); System.out.println(time.getTime()); // Sun Feb 16 08:58:01 KST 2020 // 년월일 설정 time.set(1982, 1, 19); // 1은 2월 System.out.println(time.getTime()); // Fri Feb 19 08:58:01 KST 1982 // 년월일, 시분초 설정 time.set(1982, 1, 19, 12, 34, 56); System.out.println(time.getTime()); // Fri Feb 19 12:34:56 KST 1982
clear() 메소드
- 현재
Calendar
인스턴스의 모든 필드의 값을 undefined로 설정한다.