Calendar와 Date

  • Date : 날짜와 시간을 다룰 목적으로 제공되는 클래스(JDK 1.0 ~)

    • java.util.Date;
  • Calendar : Date를 보강한 클래스 (JDK 1.1 ~ )

    • java.util.Calendar;
  • java.time패키지 : 기존 단점 보강 (JDK 1.8 ~ )

    • java.time 패키지만 배우면 좋을텐데, 아쉽게도 Calendar와 Date는 자바의 탄생부터 지금까지 20년 넘게 사용해왔고, 지금도 계속 사용되고 있음

    • 기능을 깊게 배울 필요는 없고 간단한 정도만 이해하고 필요할 때 활용하는 정도



Calendar와 GregorianCalendar

  • Calendar : 추상클래스, 직접 객체를 생성할 수 없고, 메서드를 통해서 완전히 구현된 클래스의 인스턴스를 얻어야 함

    • Calendar cal = new Calendar(); // 에러 - 추상클래스는 인스턴스 생성 불가

    • Calendar cal = Calendar.getInstance(); // OK - getInstance()메서드는 Calendar 클래스를 구현한 클래스의 인스턴스를 반환

  • Caledar를 상속받아 완전히 구현한 클래스

    • GregorianCalendar : Calendar를 상속받아 오늘날 전세계 공통으로 사용하고 있는 그레오리력에 맞게 구현한 것, 태국을 제외한 나머지 국가에서 사용

    • BuddhistCalendar



Calendar.getInstance()

  • staic

    • 메서드 내의 코드에서 인스턴스 변수를 사용하거나 인스턴스 메서드를 호출하지 않기 때문

    • getInstance()가 static이 아니라면, 객체를 생성한 다음에 호출해야하는데 Calendar는 추상클래스이므로 객체 생성이 불가능하기 때문

  • 시스템의 국가와 지역 설정을 확인하여 구현된 인스턴스를 반환

    • 태국 - BuddhistCalendar 인스턴스 반환

    • 그 외 - GreporianCalendar 인스턴스 반환

  • 인스턴스를 직접 사용하지 않고 메서드를 통해 인스턴스를 반환받게 하는 이유

    • 최소한의 변경으로 프로그램이 동작하기 위하여

    • 새로운 역법이 추가되는 경우 Calendar의 getInstance() 내용만 변경되면 됨

  • 기본적으로 현재 시스템의 날짜와 시간에 대한 정보를 담고 있음

    • 원하는 날짜나 시간으로 설정하려면 set 메서드 사용



Calendar와 Date간의 변환

  • Calendar가 추가되면서 Date는 대부분의 메서드가 ‘deprecated’되어서 잘 사용되지 않음

    • deprecated : Java API 문서에 더이상 사용을 권장하지 않는 대상에 붙어있음
  • 여전히 Date를 필요로 하는 메서드들이 있기 때문에 Calendar를 Date로 또는 그 반대로 변환할 일이 생김

/* Calendar → Date */
Calendar cal1 = Calendar.getInstance();
    . . .
Date d - new Date(cal.getTimeInMillis()); // Date(long date)

/* Date → Calendar */
Date d = new Date();
    . . .
Calendar cal = Calendar.getInstance();
cal.setTime(d);



Calendar - int get(int field)

  • 원하는 필드의 값을 얻어오기

  • get메서드의 매개변수로 사용되는 int 값들은 Calendar에 정의된 static 상수

  • 자주 쓰는 상수

    • Calendar.YEAR; // [년]

    • Calendar.MONTH; // [월] 값의 범위 0~11 임을 참고, +1을 해야 월 수가 됨

    • Calendar.WEEK_OF_YEAR; // [이 해의 몇 째 주]

    • Calendar.WEEK_OF_MONTH; // [이 달의 몇 째 주]

    • Calendar.DATE; // [이 달의 몇 일]

    • Calendar.DAY_OF_MONTH; // [이 달의 몇 일]

    • Calendar.DAY_OF_YEAR; // [이 해의 몇 일]

    • Calendar.DAY_OF_WEEK; // [요일(1~7, 1:일요일)]

    • Calendar.DAY_OF_WEEK_IN_MONTH; // [이 달의 몇 번째 요일] (ex) 이 달의 2번째 목요일 → 2

    • Calendar.AM_PM; // [오전오후(0:오전, 1:오후)]

    • Calendar.HOUR; // [시간(0~11)]

    • Calendar.HOUR_OF_DAY; // [시간(0~23)]

    • Calendar.MINUTE; // [분(0~59)]

    • Calendar.SECOND; // [초(0~59)]

    • Calendar.MILLISECOND; // [1000분의 1초(0~999)]

    • Calendar.ZONE_OFFSET; // [TimeZone(-12 ~ +12)]

    • Calendar.DATE; // [이 달의 마지막 일]

    • 더 많은 것은 Java API 문서 참고



Calendar - 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)



Calendar - clear 메서드

  • clear() : 모든 필드 초기화

  • clear(int field) : 지정된 필드 값을 기본 값으로 초기화

  • 각 필드의 기본 값 : JAVA API 문서에서 GregorianCalendar 참고



Calendar - 두 날짜간의 차이 구하기

  • 두 날짜를 최소 단위인 초단위로 변경 후 차이 계산



Calendar - add 메서드

  • add(int field, int amount) : 지정된 필드의 값을 원하는 만큼 증가 또는 감소

  • 다음 달 1일에서 하루를 빼면 이번 달의 마지막 일을 알 수 있음

    • getActualMaximum(Calendar.DATE)를 사용해도 알 수 있음



Calendar - roll 메서드

  • roll(int field, int amount) : 지정된 필드의 값을 원하는 만큼 증가 또는 감소 (단, 다른 필드에 영향 X)

    • 예) 59초 + 1초여도, 분은 영향받지 않고, 00초로 변경

    • 예외) 일 필드(Calendar.DATE)가 말일(end of month)일 때, roll 메서드를 이용해 월 필드(Calendar.Month)를 변경하면 일 필드(Calendar.DATE)에 영향을 미칠 수 있음 (add도 마찬가지)

    • 예외 예시) 3월 말(31) -> 2월 말(28)



Calendar - 기준일자와 음수

  • Calendar의 경우 1970년 1월 1일 기준이므로, 이전 날짜는 getTimeInMillis()를 호출할 경우 음수를 결과로 얻음