Date클래스는 jdk1 부터 존재했지만 매우 부족한 구성으로 1.1부터 Calendar클래스를, jdk 8이상 부터는 java.time패키지로 기존의 단점들을 개선한 새로운 클래스들을 사용할 수 있게 됐다.
Calendar는 추상클래스이므로 메서드를 통해 완전히 구현된 클래스의 인스턴스를 얻어야한다.
Calendar cal = Calendar.getInstance();
getInstance()는 태국의 경우 BuddhistCalendar를 반환하고, 나머지는 GregorianCalendar
BuddhistCalendar
불교력
GregorianCalendar
태양력
인스턴스를 직접 생성하지 않고 메서드를 통해 받환받게 하는 이유는 최소한의 변경으로 프로그램이 동작할 수 있도록 하기 위해서 이다.
class MyApplication {
public static void main(String[] args) {
Calendar cal = new GregorianCalendar(); // 경우에 따라 바뀜
...
}
}
위 방법을 사용하면 태국등의 다른 역법(Calendar)을 사용하는 국가에서는 사용하기 힘든 태양력으로만 나오게 된다. getInstance()를 통해 자동으로 해당 나라에 맞는 역법이 오게 된다.
import java.util.Calendar;
public class CalendarExample {
public static void main(String[] args) {
Calendar today = Calendar.getInstance();
System.out.println("이 해의 년도 : " + today.get(Calendar.YEAR));
System.out.println("월 : " + today.get(Calendar.MONTH) + 1);
// month의 경우 0~11을 반환한다. 1월이 0 12월이 11이다.(불편함)
System.out.println("이 해의 몇 째 주 : " + today.get(Calendar.WEEK_OF_YEAR));
System.out.println("이 달의 몇 째 주 : " + today.get(Calendar.WEEK_OF_MONTH));
// Date와 DAY_OF_MONTH는 같다.
System.out.println("이 달의 몇 일 : " + today.get(Calendar.DATE));
System.out.println("이 달의 몇 일 : " + today.get(Calendar.DAY_OF_MONTH));
System.out.println("이 해의 몇 일 : " + today.get(Calendar.DAY_OF_YEAR));
System.out.println("요일(1~7, 1:일요일) : " + today.get(Calendar.DAY_OF_WEEK));
System.out.println("이 달의 몇 째 요일 : " + today.get(Calendar.DAY_OF_WEEK_IN_MONTH));
System.out.println("오전_오후(0:오전, 1:오후) : " + today.get(Calendar.AM_PM));
System.out.println("시간(0~11): " + today.get(Calendar.HOUR));
System.out.println("시간(0~23): " + today.get(Calendar.HOUR_OF_DAY));
System.out.println("분(0~59): " + today.get(Calendar.MINUTE));
System.out.println("초(0~59): " + today.get(Calendar.SECOND));
System.out.println("1000분의 1초(0~999) : " + today.get(Calendar.MILLISECOND));
// 천분의 1초를 시간으로 표시하기 위해 3600000으로 나누었다.(1시간 + 60 * 60초)
System.out.println("TimeZone(-12~+12) : " + (today.get(Calendar.ZONE_OFFSET)/(60*60*1000)));
System.out.println("이 달의 마지막 날 : " + today.getActualMaximum(Calendar.DATE));
// 이 달의 마지막 일을 찾는다.
}
}
getInstance()를 통해서 얻은 인스턴스는 기본적으로 현재 시스템의 날짜와 시간에 대한 정보를 담고 있다. 원하는 날짜나 신가으로 설정하려면 set메서드를 사용한다.
get(Calendar.MONTH)는 참고로 0~11의 값을 반환하므로 1을 더해서 사용하자.
import java.util.Calendar;
public class CalendarExample2 {
public static void main(String[] args) {
// 요일은 1부터 시작하기 때문에, DAY_OF_WEEK[0]은 비워둔다
final String[] DAY_OF_WEEK = {"","일","월","화","수","목","금","토"};
Calendar date1 = Calendar.getInstance();
Calendar date2 = Calendar.getInstance();
// month의 경우 0부터 시작하기 때문에 4월인 경우, 3으로 지정해야 한다.
// date1.set(2019, Calendar.APRIL, 29);와 같이 할 수도 있다.
System.out.println("date1은 " + toString(date1) + DAY_OF_WEEK[date1.get(Calendar.DAY_OF_WEEK)] + "요일이고,");
System.out.println("오늘(date2)은 " + toString(date2) + DAY_OF_WEEK[date2.get(Calendar.DAY_OF_WEEK)] + "요일입니다.");
// 두 날짜 간의 차이를 얻으려면, getTiemInMillis() 천분의 일초 단위로 변환해야 한다.
long difference = (date2.getTimeInMillis() - date1.getTimeInMillis()) / 1000;
System.out.println("그 날(date1)부터 지금(date2)까지 " + difference + "초가 지났습니다.");
System.out.println("일(day)로 계산하면 " + difference/(24*60*60) + "일입니다.");
}
public static String toString(Calendar date) {
return date.get(Calendar.YEAR) + "년 " + (date.get(Calendar.MONTH) + 1) + "월 " + date.get(Calendar.DATE) + "일 ";
}
}
위 코드는 두 Calendar의 시간 차이를 계산하는 예제이다.
import java.util.Calendar;
public class CalendarExample3 {
public static void main(String[] args) {
final int[] TIME_UNIT = {3600, 60, 1}; // 큰 단위를 앞에 놓는다.
final String[] TIME_UNIT_NAME = {"시간 ", "분 ", "초 "};
Calendar time1 = Calendar.getInstance();
Calendar time2 = Calendar.getInstance();
time1.set(Calendar.HOUR_OF_DAY, 10); // time1의 시간을 10으로 설정
time1.set(Calendar.MINUTE, 20); // time1의 분을 20으로 설정
time1.set(Calendar.SECOND, 30); // time1의 초를 30으로 설정
time2.set(Calendar.HOUR_OF_DAY, 20); // time2를 20시 30분 10초로 설정
time2.set(Calendar.MINUTE, 30);
time2.set(Calendar.SECOND, 10);
System.out.println("time1 :" + time1.get(Calendar.HOUR_OF_DAY)+"시 "+time1.get(Calendar.MINUTE)+"분 "+time1.get(Calendar.SECOND)+"초");
System.out.println("time2 :" + time2.get(Calendar.HOUR_OF_DAY)+"시 "+time2.get(Calendar.MINUTE)+"분 "+time2.get(Calendar.SECOND)+"초");
long difference = Math.abs(time2.getTimeInMillis() - time1.getTimeInMillis())/1000;
System.out.println("time1과 time2의 차이는 " + difference + "초 입니다.");
String tmp = "";
for(int i = 0; i < TIME_UNIT.length; i++) {
tmp += difference/TIME_UNIT[i] + TIME_UNIT_NAME[i];
difference %= TIME_UNIT[i];
}
System.out.println("시분초로 변환하면 " + tmp + "입니다.");
}
}
위 코드는 두 개의 Calendar를 초 단위로 차이를 구한 다음, 시분초로 바꿔 출력한다.
가장 큰 단위인 시간(3600초)로 나누고 남은 나머지를 다시 분 단위(60초)로 나누면 그 나머지는 초 단위 값이 된다.
import java.util.Calendar;
public class CalendarExample4 {
public static void main(String[] args) {
Calendar date = Calendar.getInstance();
date.set(2023, 11, 11); // 2023년 11월 11일
System.out.println(toString(date));
System.out.println("= 1일 후 =");
date.add(Calendar.DATE, 1);
System.out.println(toString(date));
System.out.println("= 6달 전 =");
date.add(Calendar.MONTH, -6);
System.out.println(toString(date));
System.out.println("= 31일 후 =");
date.add(Calendar.DATE, 31);
System.out.println(toString(date));
}
public static String toString(Calendar date) {
return date.get(Calendar.YEAR) + "년 " + (date.get(Calendar.MONTH) + 1) + "월 " + date.get(Calendar.DATE) + "일";
}
}
위 코드는 일정 날짜 date로부터의 전 후 시간을 계산 하는 코드이다.
Date는 대부분의 메서드가 'deprecated'되어 잘 사용하지 않지만 여전히 일부 메서드는 'Date'를 필요로 한다. 따라서 Date - Calendar 간의 변환이 필요하다.
Calendar cal = Calendar.getInstance();
...
Date d = new Date(cal.getTimeInMillis()); // Date(long date)
Date d = new Date();
...
Calendar cal = Calendar.getInsatance();
cal.setTime(d)