날짜와 시간

박주현·2022년 11월 15일
0

혼공

목록 보기
10/20

Calendar와 Date

Calenda와 GregorianCalendar

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

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

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

Calendar를 상속받아 완전히 구현한 클래스로는 GregorianCalendar와 BuddhistCalendar가 있는데 getInstance()는 시스템의 국가와 지역설정을 확인해서 태국인 경우에는 BuddhistCalendar의 인스턴스를 반환하고, 그 외에는 GregorianCalendar의 인스턴스를 반환한다.
GregorianCalendar는 Calendar를 상속받아 오늘날 전세계 공통으로 사용하고 있는 그레고리력에 맞게 구현한 것으로 태국을 제외한 나머지 국가에서는 그레고리력을 사용하면 된다.
인스턴스를 직접 생성해서 사용하지 않고 이처럼 메서드를 통해서 인스턴스를 반환하게 하는 이유는 최소한의 변경으로 프로그램이 동작할 수 있도록 하기 위한 것이다.

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

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

Class MyApplication {
	public static void main(String[] args) {
		Calendar cal = Calendar.getInstance();

	}
}

Date와 Calendar간의 변환

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

Calendar 예제

	public static void main(String[] args) {
		// 기본적으로 현재날짜와 시간으로 설정된다.
		Calendar today = Calendar.getInstance();

		System.out.println("이 해의 년도 : " + today.get(Calendar.YEAR));
		System.out.println("월(0~ 11, 0:1월) : " + (today.get(Calendar.MONTH) + 1));
		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:월요일, ... 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~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)로 얻어오는 값의 범위가 1~12가 아닌 0~11이라는 것이다. 그래서 get(Calendar.MONTH)로 얻어오는 값이 0이면 1월을 의미하고, 11이면 12월을 의미한다.


두 날짜간의 차이를 구하는 예제

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부터 시작하기 때문 8월인 경우, 7로 지정해야한다.
		// date1.set(2015, Calendar.AUGUST, 15); 와 같이 할 수도 있다.
		date1.set(2015, 7, 15); // 2015년 8월 15일로 지정한다.
		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 + "초가 지났습니다.");
		// 1일 = 24 * 60 *60
		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) + "일 ";
	}

두 개의 시간 데이터로 부터 초 단위로 차이를 구한 다음, 시분초로 바꿔 출력하는 예제이다. 가장 큰 단위인 시간 단위(3600초)로 나누고 남은 나머지를 다시 분 단위(60초)로 나누면 그 나머지는 초 단위의 값이 된다.

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의 10시 20분 30초로 설정
		time1.set(Calendar.HOUR_OF_DAY, 10);
		time1.set(Calendar.MINUTE, 20);
		time1.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.get(Calendar.HOUR_OF_DAY) + "시 " + time1.get(Calendar.MINUTE) + "분 "
				+ time1.get(Calendar.SECOND) + "초");
		System.out.println(
				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 + "입니다.");

	}

SimpleDateFormat

날짜를 계산할 때 Date와 Calendar를 사용해서 날짜를 계산하는 방법을 봤는데,
이제는 출력하는 방법에 대해서 배울 차례이다.
Date와 Calendar만으로 날짜 데이터를 원하는 형태로 다양하게 출력하는 것은 불편하고 복잡하다. 그러나 SimpleDateFormat을 사용하면 이러한 문제들이 간단히 해결된다.

DateFormat은 추상클래스로 SimpleDateFormat의 조상이다. DateFormat은 추상클래스이므로 인스턴스를 생성하기 위해서는 getDateInstance()와 같은 static메서드를 이용해야 한다. getDateInstance()에 의해서 반환되는 것은 DateFormat을 상속받아 완전하게 구현한 SimpleDateFormat인스턴스이다.

사용 방법

Date today = new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");

// 오늘 날짜를 yyyy-MM-dd형태로 변환하여 반환한다.
String result = df.format(today);

사용 예제

public static void main(String[] args) {
		Date today = new Date();

		SimpleDateFormat sdf1, sdf2, sdf3, sdf4;
		SimpleDateFormat sdf5, sdf6, sdf7, sdf8, sdf9;

		sdf1 = new SimpleDateFormat("yyyy-MM-dd");
		sdf2 = new SimpleDateFormat("yy년 MMM dd일 E요일");
		sdf3 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
		sdf4 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss a");

		sdf5 = new SimpleDateFormat("오늘은 올 해의 D번째 날입니다.");
		sdf6 = new SimpleDateFormat("오늘은 이 달의 d번째 날입니다.");
		sdf7 = new SimpleDateFormat("오늘은 올 해의 w번째 주입니다.");
		sdf8 = new SimpleDateFormat("오늘은 이 달의 W번째 주입니다.");
		sdf9 = new SimpleDateFormat("오늘은 이 달의 F번째 E요일입니다.");

		System.out.println(sdf1.format(today));
		System.out.println(sdf2.format(today));
		System.out.println(sdf3.format(today));
		System.out.println(sdf4.format(today));
		System.out.println();
		System.out.println(sdf5.format(today));
		System.out.println(sdf6.format(today));
		System.out.println(sdf7.format(today));
		System.out.println(sdf8.format(today));
		System.out.println(sdf9.format(today));

	}

Date인스턴스만 format메서드에 사용될 수 있기 때문에 Calendar인스턴스를 Date인스턴스로 변환하는 방법을 보여 주는 예제이다.

public static void main(String[] args) {
		Calendar cal = Calendar.getInstance();
		cal.set(2005, 9, 3); // 2005년 10월 3일 - Month는 0~11 의 범위를 갖는다.

		Date day = cal.getTime(); // Calendar를 Date로 변환

		SimpleDateFormat sdf1, sdf2, sdf3, sdf4;

		sdf1 = new SimpleDateFormat("yyyy-MM-dd");
		sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
		sdf3 = new SimpleDateFormat("yy-MM-dd E요일");
		sdf4 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss a");

		System.out.println(sdf1.format(day));
		System.out.println(sdf2.format(day));
		System.out.println(sdf3.format(day));
		System.out.println(sdf4.format(day));

	}

0개의 댓글