본문 바로가기

복습

[Java 복습] Clendar 클래스

날짜와 시간

java.util.Date

  • 날짜와 시간을 다룰 목적으로 만들어진 클래스(JDK 1.0)
  • Date의 메서드는 거의 deprecated 되었지만, 여전히 쓰이고 있다.

 

java.util.Calendar

  • Date 클래스를 개선한 새로운 클래스(JDK 1.1)
  • 여전히 단점이 존재

 

java.time 패키지

  • Date와 Calendar의 단점을 개선한 새로운 클래스들을 제공(JDK 1.8)
  • LocalDate, LocalTime, LocalDateTime 세분화해서 클래스를 나눔
  • 불변으로 처리해야 함

 

Calendar 클래스

추상 클래스이므로 getInstance( )를 통해 구현된 객체를 얻어야 한다.

Calendar cal = new Calendar(); // 에러!! 추상클래스는 인스턴스를 생성할 수 없다.

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

 

 

get( ): 날짜와 시간 필드 가져오기 - int get(int field)

Calendar cal = Calendar.getInstance(); // 현재 날짜와 시간으로 셋팅
int thisYear = cal.get(Calendar.YEAR); // 올해가 몇년인지 알아낸다.
int lastDayOfMonth = cal.getActualMaximum(Calendar.DATE); // 이 달의 마지막날

 

 

Calendar 에 정의된 필드

  • YEAR: 년
  • MONTH: 월(0부터 시작)
  • WEEK_OF_YEAR: 1월 1일 ~ 지금 몇 번째 주인지
  • WEEK_OF_MONTH: 그 달의 몇 번째 주
  • DATE: 일
  • DAY_OF_MONTH: 그달의 몇 번째 일
  • DAY_OF_YEAR: 그 해의 몇 번째 일
  • DAY_OF_WEEK: 요일(1: SunDay)
  • DAY_OF_WEEK_IN_MONTH: 그달의 몇 번째 요일

 

  • HOUR: 시간(0 ~ 11)
  • HOUR_OF_DAY: 시간(0 ~ 23)
  • MINUTE: 분
  • SECOND: 초
  • MILLISECOND: 천분의 일초
  • ZONE_OFFSET: GMT 기준 시차
  • AM_PM: 오전/오후
public class Ex1 {
    public static void main(String[] args) {

        Calendar today = Calendar.getInstance(); // Canlendar 객체를 생성
        System.out.println("이 해의 년도: " + today.get(Calendar.YEAR));
        System.out.println("월(0~11, 0:1월): " + today.get(Calendar.MONTH));
        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));
        // 1: 일요일, 2: 월요일, 3: 화요일 ... , 7: 토요일
        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));
    }
}
이 해의 년도: 2024
월(0~11, 0:1월): 4
이 해의 몇 째 주: 18
이 달의 몇 째 주: 1
이 달의 몇 일: 4
이 달의 몇 일: 4
이 해의 몇 일: 125
요일(1 ~ 7), 1: 일요일: 7
이 달의 몇 째 요일: 1
오전_오후(0:오전, 1:오후): 1
시간(0~11): 6
시간(0~23): 18
분(0~59): 47
초(0~59): 57
1000분의 1초(0~999): 685
TimeZone(-12 ~ +12): 9
이 달의 마지막 날: 31

 

 

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

 

날짜 지정하는 방법

  • 월(MONTH)이 0부터 시작한다는 점에 주의(배열을 이용하기 때문에)
Calendar date1 = Calendar.getInstance(); // Canlendar 객체를 생성
date1.set(2024, 11, 25); // 2024년 12월 25일(11월 아님)
//date1.set(Calendar.YEAR, 2024);
//date1.set(Calendar.MONTH, 11);
//date1.set(Calendar.DATE, 25);

 

 

시간 지정하는 방법

  • 시, 분, 초는 따로 하나씩 설정해줘야 함.
Calendar time1 = Calendar.getInstance(); // Canlendar 객체를 생성
time1.set(Calendar.HOUR_OF_DAY, 10); // time1을 10시 20분 30초로 설정
time1.set(Calendar.MINUTE, 20);
time1.set(Calendar.SECOND, 30);
public class Ex2 {
    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); 와 같이 할 수도 있다.

        date1.set(2024, 11, 25); // 2024년 12월 25일으로 설정한다.
        System.out.println("date1은 " + toString(date1) + "월" + "요일이고, ");
        System.out.println("오늘(date2)은 " +
                toString(date2) + DAY_OF_WEEK[date2.get(Calendar.DAY_OF_WEEK)] + "요일입니다.");

        // 두 날짜간의 차이를 얻으려면, getTimeInMillis() 천분의 일초 단위로 변환해야한다.
        long different =
                (date2.getTimeInMillis() - date1.getTimeInMillis()) / 1000;
        System.out.println("그 날(date1)로 부터 지금(date2)까지 " + Math.abs(different) + "초가 남았습니다.");
        System.out.println("일(day)로 계산하면 " + Math.abs(different) / (24 * 60 * 60) + "일 입니다.");

    }
    public static String toString(Calendar date) {
        return date.get((Calendar.YEAR)) +  "년 " + (date.get(Calendar.MONTH) + 1)+ "월 " +
                date.get(Calendar.DATE) + "일 ";
    }
}
date1은 2024년 12월 25일 월요일이고, 
오늘(date2)은 2024년 5월 4일 토요일입니다.
그 날(date1)로 부터 지금(date2)까지 20303999초가 남았습니다.
일(day)로 계산하면 234일 입니다.

 

public class Ex3 {
    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시 20분 30초로 설정
        time1.set(Calendar.MINUTE, 20);
        time1.set(Calendar.SECOND, 30);

        time2.set(Calendar.HOUR_OF_DAY, 20); // time2을 20시 30분 10초로 설정
        time2.set(Calendar.MINUTE, 30);
        time2.set(Calendar.SECOND, 10);

        long different = Math.abs(time2.getTimeInMillis() - time1.getTimeInMillis()) / 1000;
        System.out.println("time1과 time2의 차이는 " + different + "초 입니다.");

        String tmp = "";
        for (int i = 0; i < TIME_UNIT.length; i++) {
            tmp += different/TIME_UNIT[i] + TIME_UNIT_NAME[i];
            different %= TIME_UNIT[i];
        }
        System.out.println("시,분,초로 변환하면 " + tmp + "입니다.");
    }
}
time1과 time2의 차이는 36580초 입니다.
시, 분, 초로 변환하면 10시간 9분 40초 입니다.

 

 

clear( ): Calendar 객체의 모든 필드를 초기화

Calendar dt = Calendar.getInstance(); // 현재 시간
System.out.println(new Date(dt.getTimeInMillis()));
dt.clear(); // 모든 필드를 초기화
System.out.println(new Date(dt.getTimeInMillis())); // 에포크 시간
Sat May 04 22:18:07 KST 2024
Thu Jan 01 00:00:00 KST 1970

 

clear(int field)는 Calendar 객체의 특정 필드를 초기화할 수도 있다.

Calendar dt = Calendar.getInstance(); // 현재 시간
System.out.println(new Date(dt.getTimeInMillis()));
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()));
Sat May 04 22:26:45 KST 2024
Sat May 04 12:00:00 KST 2024

 

 

add( ): 특정 필드의 값을 증가 또는 감소(다른 필드에 영향O)

roll( ): 특정필드의 값을 증가 또는 감소(다른 필드에 영향X)

Calendar date = Calendar.getInstance();
date.clear();
date.set(2024, 11, 25);

date.add(Calendar.DATE, 1);
date.add(Calendar.MONTH, 8);
public class CalendarEx {

    public static void main(String[] args) {

        int year = 2024;
        int month = 12;
        int START_DAY_OF_WEEK = 0; // 1의 요일
        int END_DAY = 0;

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

        // 월의 경우 0부터 11까지의 값을 가지므로 1을 빼주어야 한다.
        // 예를 들어 2024년 12월은 set(2024, 11, 1);
        sDay.set(year, month-1, 1); // 2024.12.1
        eDay.set(year, month, 1); // 2025. 1.1
        // 다음달의 첫날(1월 1일)에서 하루를 빼면 현재 달의 마지막 날(12월 31일)
        eDay.add(Calendar.DATE, -1); // 2024.12.31
        START_DAY_OF_WEEK = sDay.get(Calendar.DAY_OF_WEEK); // 1일이 월요일 월요일은 index:2
        END_DAY = eDay.get(Calendar.DATE); // 31

        System.out.println("       " + year + "년 " + month + "월"); 
        System.out.println(" SU MO TU WE TH FR SA");

        // 해당 월의 1일이 어느 요일인지에 따라서 공백을 출력한다.
        // 만약 1일이 수요일이면 공백을 세 번 반복해서 찍는다(일요일 부터 시작)
        // 1일이 월요일이므로 공백을 한번 찍음
        for (int i = 1; i < START_DAY_OF_WEEK; i++) {
            System.out.print("   ");
        }
        
        // 현재 n = 2 , n == 7(토요일)이 될 때마다 다음칸으로
        // 한자리 수면 2번 공백찍고, 아니면 한번만 공백 찍어서 모양 맞춰주기
        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();
            }
        }
    }
}
      2024년 12월
 SU MO TU WE TH FR SA
  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

 

Date와 Calendar 간의 변화

Date의 메서드는 대부분 deprecated 되었지만 여전히 사용

// Calendar를 Date로 변환
Calendar cal = Calendar.getInstance();
// ...
Date d = new Date(cal.getTimeInMillis()); // Date(long date)

// Date를 Calendar로 변환
Date dt = new Date();
//...
Calendar c = Calendar.getInstance();
c.setTime(dt);

 

 

형식화 클래스

  • java.text 패키지의 DecimalFomat, SimpleDateFormat
  • 숫자와 날짜를 원하는 형식으로 쉽게 출력 가능(숫자, 날짜 => 형식 문자열)
double number = 1234567.89;
DecimalFormart df = new DecimalFormat("#.#E0");
String result = df.format(number); // result = "1.2E6"(지수표현 법)

 

  • 형식 문자열에서 숫자와 날짜를 뽑아내는 기능(형식 문자열 => 숫자, 날짜)
DecimalFormart df = new DecimalFormat("#,###.##"); // 형식
Number num = df.parse("1,234,567.89"); // 모든 숫자(래퍼클래스의 최고 조상)
double d = num.doubleValue; // 1234567.89

 

 

DecimalFormat

숫자를 형식화할 때 사용(숫자 => 형식 문자열)

특정 형식의 문자열을 숫자로 변환할 때도 사용(형식 문자열 => 숫자)

참고: Integer.parseInt( )는 콤마(,)가 포함된 문자열을 숫자로 변환 못한다.

 

 

 

SimpleDateFormat

날짜와 시간을 다양한 형식으로 출력할 수 있게 해준다.

Date today = new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
// 오늘 날짜를 yyyy-MM-dd 형태로 변환하여 반환한다.
String result = df.format(today);
System.out.println(result);
2024-05-05

 

특정 형식으로 되어 있는 문자열에서 날짜와 시간을 뽑아낼 수도 있다.

DateFormat df = new SimpleDateFormat("yyyy년 MM월 dd일");
DateFormat df2 = new SimpleDateFormat("yyyy/MM/dd");

try { // try-catch문을 안 써주면 이상하게 컴파일러 에러가 뜬다..
    Date d = df.parse("2015년 11월 25일"); // 문자열을 Date로 변환, 날짜로 바꿈
    String result = df2.format(d); // 문자열로 바꿈
    String result2 = df.format(d);// 문자열로 바꿈
    System.out.println(result);
    System.out.println(result2);

} catch (ParseException pe) {

}