본문 바로가기
Java의 정석/날짜와 시간 & 형식화

Calendar 클래스 - 예제, Date 와 Calendar 간의 변환

by Hwanii_ 2023. 9. 3.
728x90
ch10 - 4 ~ 5
Calendar 클래스 - 예제

 

- set() 메서드로 날짜와 시간 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)

set() 메서드들이 다양하게 오버로딩 되어 있다.

- 날짜 지정 하는 방법. 월 (MONTH) 은 0 부터 시작한다. 주의 !

Calendar date1 = Calendar.getInstance();

date1.set(2023, 8, 03);    //  2023년 9월 3일 (월은 0부터 시작하므로, 실제 월보다 -1을 해주면 된다)

//  data1.set(Calendar.YEAR, 2023);
//  data1.set(Calendar.MONTH, 8);
//  data1.set(Calendar.DATE, 03);

위와 같이 연, 월, 일 을 한번에 set 할 수도 있고,

연, 월, 일을 단독적으로 set 할 수도 있다.

MONTH 가 0 부터 시작 하는 이유는, 당연히 배열을 사용 해서 그렇다. (인덱스는 0 부터 시작)

- 시간 지정 하는 방법.

Calendar time1 = Calendar.getInstance();

time1.set(Calendar.HOUR_OF_DAY, 13);    //  time을 13시 30분 40초로 설정.
time1.set(Calendar.MINUTE, 30);
time1.set(Calendar.SECOND, 40);

 

예제 01 )

 

컴퓨터는 년, 월, 일, 시, 분, 초 를 알지도 못하고, 알 수도 없다.

년, 월, 일, 시, 분, 초 는 사람이 보기 쉽게 하기 위함 이다.

컴퓨터는 모두 정수로 보기 때문에,
날짜와 시간을 계산 할 때, "초 단위로 계산"을 해서, 원래의 시, 분, 초 또는 년, 월, 일 로 바꾸면 된다.

(사실 java.time. 패키지를 사용 하면 더 쉽게 할 수 있지만, 이렇게도 가능 하다는것을 알 수 있다)

 

import java.util.*;

class Ex10_2 {

    public static void main(String[] args) {

        // 요일은 1부터 시작하기 때문에, DAY_OF_WEEK[0]은 비워두었다.
        final String[] DAY_OF_WEEK = {"", "일", "월", "화", "수", "목", "금", "토"};
        //  "" == 0, "일" == 1, "월" == 2, "화" == 3, "수" == 4, "목" == 5, "금" == 6, "토" == 7

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

        // month의 경우 0부터 시작하기 때문에 9월인 경우, 8로 지정해야한다.
        // date1.set(2023, Calendar.SEPTEMBER, 03);와 같이 할 수도 있다.
        date1.set(2023, 4, 07); // 2023년 5월 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; //  단위가 1000분에 1초라서, 1000으로 나눠야 한다.
        System.out.println("그 날(date1)부터 지금(date2)까지 " + difference + "초가 지났습니다.");
        System.out.println("일(day)로 계산하면 " + difference / (24 * 60 * 60) + "일입니다."); // 1일 = 24 * 60 * 60
    }

    public static String toString(Calendar date) {
        return date.get(Calendar.YEAR) + "년 " + (date.get(Calendar.MONTH) + 1)
                + "월 " + date.get(Calendar.DATE) + "일 ";

    }

}

 

[ console ]

 

 

예제 02 )

 

import java.util.*;

class Ex10_3 {

    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, 01); // time1을 1시 50분 55초로 설정
        time1.set(Calendar.MINUTE, 25);
        time1.set(Calendar.SECOND, 28);

        time2.set(Calendar.HOUR_OF_DAY, 13); // time2을 13시 50분 55초로 설정
        time2.set(Calendar.MINUTE, 50);
        time2.set(Calendar.SECOND, 55);

        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 + "입니다.");

    }

}

 

[ console ]

 

 

- clear() 메서드는 Calendar 객체의 모든 필드를 초기화.

Calendar dt = Calendar.getInstance();

System.out.println(new Date(dt.getTimeInMillis())); //  Sun Sep 03 14:56:02 KST 2023

dt.clear(); //  모든 필드를 초기화.

System.out.println(new Date(dt.getTimeInMillis())); //  Thu Jan 01 00:00:00 KST 1970
>> 1970년 1월 1일 00:00:00
>> EPOCH Time (에포크 타임)

- clear(int field) 는 Calendar 객체의 특정한 필드만 초기화.

Calendar dt = Calendar.getInstance();

System.out.println(new Date(dt.getTimeInMilles()));

dt.clear(Calendar.SECOND);      //  초를 초기화.
dt.clear(Calendar.MINUTE);      //  분을 초기화.
dt.clear(Calendar.HOUR_OF_DAY); //  시간을 초기화.
dt.clear(Calendar.HOUR);        //  시간을 초기화.

System.out.println(new Date(dt.getTimeInMillis())); //  Sun Sep 03 00:00:00 KST 2023

 

ch10 - 6 ~ 8
Calendar 클래스 - 예제

 

- add() 메서드는 특정 필드의 값을 증가 또는 감소 (다른 필드에 영향을 미침)

Calendar date = Calendar.getInstance();

date.clear();                   //  모든 필드를 초기화.
date.set(2023,8,03)             //  2023년 9월 3일로 설정.

date.add(Calendar.DATE, 1);     //  날짜 (DATE) 에 1을 더함.
date.add(Calendar.MONTH, -8);   //  월 (MONTH) 에서 8을 뺀다.

날짜에 1을 더하면, 2023년 9월 4일이 된다.
월에 8을 빼면, 2023년 1월 4일이 된다.

근데, 만약에 현재 날짜가 2023년 5월 5일 이라고 가정 해보자.
이때 날짜에 30을 더하면, 2023년 6월 5일? (4일) 이 될 것 이다.
그러니까, 날짜만 바뀌는게 아니라, 월도 바뀌는 것이다.
이렇게 날짜 필드를 수정 했는데, 월 필드도 변경 되는 메서드가 add() 메서드 이다.

- roll() 메서드는 특정 필드의 값을 증가 또는 감소 (다른 필드에 영향을 미치지 않음)

date.set(2023, 8, 03);          //  2023년 9월 3일로 설정.

date.roll(Calendar.DATE, 1);    //  날짜 (DATE) 에 1을 더함.
date.roll(Calendar.MONTH, -8);  //  월 (MONTH) 에서 8을 뺀다.

마찬가지로, 만약에 현재 날짜가 2023년 5월 5일 이라고 가정 해보자.
이때 날짜에 30을 더하면,
2023년 6월 5일이 되는게 아니라,
2023년 5월 5일이 된다.
이렇게 다른 필드에 영향을 미치지 않는 메서드가 roll() 메서드 이다.
사실 잘 사용 하지 않는데, 가끔 사용을 하긴 한다고 한다.

 

예제 03 )

 

import java.util.*;

class Ex10_4 {

    public static void main(String[] args) {

        Calendar date = Calendar.getInstance();
        date.set(2023, 4, 5);    // 2023년 5월 5일

        System.out.println(toString(date)); //  여기서, toString() 은 Object 클래스의 toString 메서드를 재정의 한게 아니라, 별도로 만든 toString() 이다.
        System.out.println();

        System.out.println("= 1일 후 =");
        date.add(Calendar.DATE, 1);
        System.out.println(toString(date));
        System.out.println();

        System.out.println("= 6달 전 =");
        date.add(Calendar.MONTH, -6);
        System.out.println(toString(date));
        System.out.println();

        System.out.println("= 31일 후(roll) =");
        date.roll(Calendar.DATE, 31);
        System.out.println(toString(date));
        System.out.println();

        System.out.println("= 31일 후(add) =");
        date.add(Calendar.DATE, 31);
        System.out.println(toString(date));
        System.out.println();
    }

    public static String toString(Calendar date) {
        return date.get(Calendar.YEAR) + "년 " + (date.get(Calendar.MONTH) + 1)
                + "월 " + date.get(Calendar.DATE) + "일";

    }

}

 

[ console ]

 

 

예제 04 )

달력 출력 하기.

 

import java.util.*;

class Ex10_5 {

    public static void main(String[] args) {    //  달력 출력 하기.

        if (args.length != 2) {
            System.out.println("Usage : java Ex10_5 2023 9");   //  2023은 args[0], 9 는 args[1] 이다. (커맨드 라인에 입력..)
            return;
        }
        int year = Integer.parseInt(args[0]);   //  ==  2023
        int month = Integer.parseInt(args[1]);  //  ==  9
        int START_DAY_OF_WEEK = 0;              //   1일의 요일
        int END_DAY = 0;

        Calendar sDay = Calendar.getInstance(); // 시작일 
        Calendar eDay = Calendar.getInstance(); // 끝일 

        // 월의 경우 0부터 11까지의 값을 가지므로 1을 빼주어야 한다. 
        // 예를 들어, 2023년 9월 3일은 sDay.set(2023, 8, 3);과 같이 해줘야 한다.
        sDay.set(year, month - 1, 1);   //  2023년
        eDay.set(year, month, 1);

        //  다음달의 첫날(10월 1일)에서 하루를 빼면 현재달의 마지막 날(9월 30일)이 된다.
        //  왜 이렇게 하냐면, 매 달마다 끝나는 날짜가 28일 일수도 있고, 30일 일수도 있고, 31일 일수도 있기 때문에,
        //  이번달 에서 한달을 더 하고, 하루를 빼면, 이번달의 마지막 날이 된다.
        eDay.add(Calendar.DATE, -1);    //  2023.9.30

        // 첫 번째 요일이 무슨 요일인지 알아낸다. (1일이 무슨 요일인지 알아내기)
        START_DAY_OF_WEEK = sDay.get(Calendar.DAY_OF_WEEK);

        // eDay에 지정된 날짜를 얻어온다. 
        END_DAY = eDay.get(Calendar.DATE);

        System.out.println("      " + year + "년 " + month + "월");
        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_DAY; i++, n++) {
            System.out.print((i < 10) ? "  " + i : " " + i);
            if (n % 7 == 0) System.out.println();
        }

    }

}

 

[ console ]

 

 

커맨드 라인에 보고싶은 년과 월을 차례대로 입력 하면,

 

 

 

이런식으로 달력을 출력 할 수 있다.

 

1. 이번달의 말일 구하기.
다음달 1일에서 1일 빼기.

2. 이번달 1일이 무슨 요일인지 구하기.

3. 요일 계산하고, 요일에 일이 없으면 공백으로 처리 하기.

4. for문을 루프 하고, 토요일 마다 줄바꿈 하면 된다.

 

ch10 - 8
Date 와 Calendar 간의 변환.

Date의 메서드는 대부분 deprecated 되었지만, 여전히 사용 한다.
(오래전 부터 사용 해와서 ..)

deprecated == 사용 하지 않을 것을 권장.

1. Calendar 를 Date 로 변환.

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

2. Date를 Calendar 로 변환.

Date d = new Date();
    ..
Calendar cal = Calendar.getInstance();
cal.setTime(d);
반응형

'Java의 정석 > 날짜와 시간 & 형식화' 카테고리의 다른 글

날짜와 시간, Calendar 클래스  (0) 2023.09.03