본문

Calendar와 Date

반응형

# Calendar와 Date

Calendar는 추상클래스이기 때문에 직접 객체를 생성할 수 없고,
메서드를 통해서 완전히 구현된 클래스의 인스턴스를 얻어야 한다.

1
2
3
4
Calendar cal = new Calendar();    // 에러, 추상클래스는 인스턴스를 생성할 수 없다.
 
// OK, getInstance()메서드는 Calendar클래스를 구현한 클래스의 인스턴스를 반환한다.
Calendar cal = Calendar.getInstance();
cs


GregorianCalendar는 Calendar를 상속받아 오늘날 전세계 공통으로 사용하고 있는 그레고리력에 맞게 구현한 것으로 

태국을 제외한 나머지 국가에서는 GregorianCalendar를 사용하게 된다. 

인스턴스를 직접 생성해서 사용하지 않고 이처럼 메서드를 통해서 인스턴스를 반환받게 하는 이유
최소한의 변경으로 프로그램이 동작할 수 있도록 하기 위한 것이다.


1
2
3
4
5
class MyApplication {
    public static void main(String args[]) {
        Calendar cal = new GregorianCalendar(); // 경우에 따라 이 부분을 변경해야 한다.
    }
}
cs

만일 위와같이 특정 인스턴스를 생성하도록 프로그램이 작성되어 있다면, 다른 종류의 역법(calendar)을 사용하는 국가에서 실행한다던가 새로운 역법이 추가된다던가 하는 경우, 즉 다른 종류의 인스턴스를 필요로 하는 경우에 MyApplication을 변경해야 하는데 비해 아래와 같이 메서드를 통해서 인스턴스를 얻어오도록 하면 MyApplication을 변경하지 않아도 된다.


1
2
3
4
5
class MyApplication {
    public static void main(String args[]) {
        Calendar cal = Calendar.getInstance();
    }
}
cs


대신 getInstance()의 내용은 달라져야 하겠지만, MyApplication이 변경되지 않아도 된다는 것이 중요하다.
getInstance()메서드가 static인 이유는 메서드 내의  코드에서 인스턴스 변수를 사용하거나 인스턴스 메서드를 호출하지 않기 때문이며,
또 다른 이유는 getInstance()가 static이 아니라면 위와 같이 객체를 생성한 다음에 호출해야 하는데 Calendar는 추상클래스이기 때문에 객체를 생성할 수 없기 때문이다.


getInstance()를 통해서 얻은 인스턴스는 기본적으로 현재 시스템의 날짜와 시간에대한 정보를 담고 있다.
원하는 날짜나 시간으로 설정하려면 set메서드를 사용하면 된다.


System.out.pirntln("월(0~11, 0:1월) : " + today.get(Calendar.MONTH);

한가지 주의해야할 점은 get(Calendar.MONTH)로 얻어오는 값의 범위가 1~12가 아닌 0~11이라는 것이다. 그래서 get(Calendar.MONTH)로 얻어오는 값이 0이면 1월을 의미하고 11이면 12월을 의미한다.


Source01) calendarEx01.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package calendarEx;
 
import java.util.Calendar;
 
public class calendarEx01 {
 
    public static void main(String[] args) {
        // 요일은 1부터 시작하기 때문에, DAY_OF_WEEK[0]은 비워둔다.
        final String[] DAY_OF_WEEK = { """일""월""화""수""목""금""토" };
 
  // .getInstance() 오늘의 날짜정보를 받아옴
        Calendar date1 = Calendar.getInstance();
        Calendar date2 = Calendar.getInstance();
 
        // month의 경우 0부터 시작하기 때문에 8월인 경우, 7로 지정해야 한다.
        date1.set(200517); // 2005년 2월 7일로 날짜를 설정한다.
        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)] + "요일입니다.");
 
        // 두 날짜간의 차이를 얻으려면, getTimeInMillis()를 이용해서 천분의 일초 단위로 변환해야한다.
        long difference = (date2.getTimeInMillis() - date1.getTimeInMillis()) / 1000;
        System.out.println("그 날(date1)부터 지금(date2)까지" + difference + "초가 지났습니다.");
 
        System.out.println("일(day)로 계산하면 " + difference / (24 * 60 * 60+ "일 입니다."); // 1일 = 24*60*60                
    }
 
    private static String toString(Calendar date) {
        return date.get(Calendar.YEAR) + "년" + (date.get(Calendar.MONTH) + 1+ "월 " + date.get(Calendar.DATE) + "일 ";
    }
}
cs

Result)

1
2
3
4
date1은 2005년2월 7일 월요일이고, 
오늘(date2)은 2016년1월 7일 목요일입니다.
그 날(date1)부터 지금(date2)까지344390400초가 지났습니다.
일(day)로 계산하면 3986일 입니다.
cs


두 개의시간 데이터로부터 초 단위로 차이를 구한 다음, 시분초로 바꿔 출력하는 예제이다. 

가장 큰 단위인 시간 단위(36000초)로 나누고 나머지를 다시 분 단위(60초)로 나누면 그 나머지는 초 단위의 값이 된다.


Source02)
 
CalendarEx02.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package calendarEx;
 
import java.util.Calendar;
 
public class CalendarEx02 {
 
    public static void main(String[] args) {
        final int[] TIME_UNIT = { 3600601 }; // 큰 단위를 앞에 넣는다.
        final String[] TIME_UNIT_NAME = { "시간 ""분 ""초 " };
 
        Calendar time1 = Calendar.getInstance();
        Calendar time2 = Calendar.getInstance();
 
        // time1의 시간을 10시 20분 30초로 설정한다.
        time1.set(Calendar.HOUR_OF_DAY, 10);
        time1.set(Calendar.MINUTE, 20);
        time2.set(Calendar.SECOND, 30);
 
        // time2의시간을 20시 30분 10초로 설정한다.
        time2.set(Calendar.HOUR_OF_DAY, 20);
        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() - Math.abs(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 + "입니다.");
    }
 
}
cs

Result)

1
2
3
4
time1 : 10시 20분 43초
time2 : 20시 30분 10초
time1과 time2의 차이는 36567초 입니다.
시분초로 변환하면 10시간 9분 27초 입니다.
cs


커맨드라인으로 년과 월을 입력하면 달력을 출력하는 예제이다.
다음 달의1일에서 하루를 빼면 이번 달의 마지막 일을 알 수 있다는 것을 기억하자.

예를 들면 2월의 마지막 날을 알고 싶을 때 3웛 1일에서 하루를 빼면 된다.


Source03) Calendar_Ex.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import java.util.Calendar;
 
public class Calendar_Ex {
 
    public static void main(String[] args) {
        if (args.length != 2) {
            System.out.println("사용법 : java CalendarEx03 2016 1");
            return;
        }
 
        int year = Integer.parseInt(args[0]);
        int month = Integer.parseInt(args[1]);
 
        int START_DAY_OF_WEEK = 0;
        int END_OF_DAY = 0;
 
        Calendar startDay = Calendar.getInstance(); // 시작일
        Calendar endDay = Calendar.getInstance(); // 종료일
 
        // 월의 경우 0부터 11까지 값을 가지므로 1을 빼주어야 한다.
        // 예를들어, 2014년 11월 1일은 startDay.set(2014, 10,1); 과 같이 해줘야 한다.
        startDay.set(year, month - 11);
        endDay.set(year, month, 1);
 
        // 다음달의 첫날에서 하루를 빼면 현재달의 마지막 날이 된다.
        // 12월 1일에서 하루를 빼면 11월 30일이 된다.
        endDay.add(Calendar.DATE, -1);
 
        // 첫 번째 요일이 무슨 요일인지 알아낸다.
        START_DAY_OF_WEEK = startDay.get(Calendar.DAY_OF_WEEK);
        // endDay에 지정된 날짜를 얻어온다.
        END_OF_DAY = endDay.get(Calendar.DATE);
 
        System.out.println("    " + args[0+ "년 " + args[1+ "월");
        System.out.println(" SU MO TU WE TH FR SA");
 
        // 해당 월의 1일이 어느 요일인지에 따라서 공백을 출력한다.
        // 만일 1일이 수요일이라면 공백을 세 번 찍는다. (일요일부터 시작)
        for (int i = 1; i < START_DAY_OF_WEEK; i++) {
            System.out.print("   ");
        }
 
        for (int i = 1, n = START_DAY_OF_WEEK; i <= END_OF_DAY; i++, n++) {
            System.out.print((i < 10) ? "  " + i : " " + i);    // 공백 2번, 1번
            if (n % 7 == 0)
                System.out.println();
        }
    }
 
}
cs

Result)





출처 및 참고자료 : JAVA의정석(남궁성 저)

반응형

공유

댓글