LANGUAGE/Java

날짜와 시간, 형식화

Doraemon_lulu 2023. 11. 23. 17:43

날짜와 시간

java.util.Date

  • 정의
    - java.util 패키지에 속하는 클래스
    - 날짜와 시간을 다루기 위한 목적으로 만들어진 클래스 (JDK 1.0)
    - Date의 메서드는 거의 deprecated 되었으나(앞으로 사용하지 않도록 권장함에 대한 의미), 여전히 많이 쓰이고 있음.
    - 날짜와 시간을 항상 함께 다루어야 하는 단점이 있음.

java.util.Calendar

  • 정의
    - java.util 패키지에 속하는 클래스
    - Date 클래스를 개선한 새로운 클래스이며, 여전히 단점이 존재함. (JDK 1.1)
    날짜와 시간을 항상 함께 다루어야 하는 단점이 있음.
    - But, 약 17년이라는 오랜 기간 사용되었음.

  • 특징
    - 추상 클래스이며, getInstance()를 통해 구현된 객체를 얻어야 함. 
    - 인스턴스를 생성할 경우, 사용자들이 자유롭게 다양한 캘린더를 호출하여 사용하기 어렵기 때문에 다음과 같이 getInstance() 메서드를 호출하여 사용해야 함.
    - getInstance() 메서드를 변경하여 다양한 캘린더를 사용할 수 있음.
/* 추상클래스는 인스턴스를 생성할 수 없음 */
// Calendar cal = new Calendar

/* 경우에 따라 getInstance() 메서드를 수정하여 사용할 수 있음. */
Calendar cal = Calendar.getInstance(); // 현재 날짜와 시간으로 셋팅됨.
int thisYear = cal.get(Calendar.YEAR); // 올해가 몇년도인지 확인함.
int lastDayOfMonth = cal.getActualMaximum(Calendar.DATE); // 이 달의 마지막날을 확인함.

 

  • Calendar에 정의된 필드
    - Month (월): 0(= 1월) ~ 11(= 12월)

    - 그 해 (= 1월 1일 이후)
    - 요일: 1(= 일요일) ~ 7(토요일)
  • 날짜(Date)
필드명 기능
YEAR
MONTH 월 (*0부터 시작)
DATE 일 (= DAY_OF_MONTH)
WEEK_OF_YEAR 그 해의 몇 번째 주
WEEK_OF_MONTH 그 달의 몇 번째 주
DAY_OF_YEAR 그 해의 몇 번째일
DAY_OF_MONTH 그 달의 몇 번째일
DAY_OF_WEEK 요일
DAY_OF_WEEK_IN_MONTH 그 달의 몇 번째 요일

 

  • 시간 (Time)
필드명 기능
HOUR 시간 (0 ~ 11)
HOUR_OF_DAY 시간 (0 ~ 23) - 24시간형
MINUTE
SECOND
MILLISECOND 1/1000 초
ZONE_OFFSET GMT 기준 시차 (1/1000초 단위)
* KOREA: +9 (시간)
AM_PM 오전 / 오후

 

1) Calendar의 getInstance() 메서드 생성

 Calendar today = Calendar.getInstance();
2) Calendar 객체 today의 필드 호출

 today.get(Calendar.__(필드명)__)

import java.util.*;

class Ex10_1 {
	public static void main(String[] args) {
		
		/* 기본적으로 현재의 날짜 및 시간으로 설정됨. */ 
		Calendar today = Calendar.getInstance();
        
		System.out.println("이번 년도 : " + today.get(Calendar.YEAR));
		System.out.println("이번 달 : " + 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));
	  	System.out.println("요일 : " + today.get(Calendar.DAY_OF_WEEK));
	 	System.out.println("이번 달의 몇 번째 요일 : " + today.get(Calendar.DAY_OF_WEEK_IN_MONTH));
	 	
	 	// Time 
		System.out.println("오전/오후 : " + today.get(Calendar.AM_PM));
		System.out.println("시간 : " + today.get(Calendar.HOUR));
		System.out.println("시간(24시간 기준): " + 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));
		// 1000분의 1초를 시간 단위로 표현하기 위해 60X60(1시간=360초) X 1000(초)으로 계산함. 
		System.out.println("TimeZone(-12~+12): " + (today.get(Calendar.ZONE_OFFSET)/(60*60*1000))); 
		System.out.println("이달의 마지막 날 : " + today.getActualMaximum(Calendar.DATE) ); 
	}
}

 

▼  [출력 결과] 

올해 : 2023

이번 달 : 10

올해 몇 번째 주 : 47

이번 달 몇 번째 주 : 4

이 달의 몇 일 : 22

이 달의 몇 일 : 22

이번 년의 몇 일 : 326

요일 : 4

이번 달의 몇 번째 요일 : 4

오전/오후 : 1

시간 : 9

시간(24시간 기준): 21

분(0 ~ 59) : 44

초(0 ~ 59): 6

1000분의 1초(0~999): 313

TimeZone(-12~+12): 9

이달의 마지막 날 : 30

 

  • set() 으로 날짜와 시간 지정
    - 월(MONTH)의 경우, 0부터 시작하기 때문에 0은 1월을 의미하며 11은 12월을 의미함을 주의해야 함.  
     ∵ 참고로 월(MONTH)의 경우 '배열'을 이용하기 때문에 0부터 시작함.
// 날짜와 시간을 지정하는 방법
void set(int field, int value);
void set(int year, int month, int date); // 년, 월, 일
void set(int hourOfDay, int minute, int second); // 시, 분, 초

Calendar date = Calender.getInstance(); // Calendar 객체(data) 생성 
date.set(2023, 10, 22); // 2023년 11월 22일 (10월이 아님을 주의!!)

// void set(int field, int value); 와 같이 각각의 field 및 value 값을 사용하여 표현하는 경우
// void set(Calendar.YEAR, 2023); // 2023년
// void set(Calendar.MONTH, 10);  // 11월 
// void set(Calendar.DATE, 22);   // 22일

 

  • getTimeInMillis() 메서드
    - 날짜 및 시간(시,분,초)을 millisecond(ms)로 변환하는 메서드 (*1/1000초로 변환; 1000ms = 1s) 
    - 형태: 객체명.getTimeInMillis / 1000
import java.util.*;

class Ex10_2 {
	public static void main(String[] args) {
		// 요일(DAY_OF_WEEK)에 대한 배열 생성 
		final String[] DAY_OF_WEEK = {"","일","월","화","수","목","금","토"};
        
 		// Calendar 객체들(birth, today)을 각각 생성함.
		Calendar birth = Calendar.getInstance();
		Calendar today = Calendar.getInstance();

		// birth는 "2019년 4월 29일"로 설정함. 
		birth.set(2019, 3, 29); 
		System.out.println("birth는 " + toString(birth) 
                  + DAY_OF_WEEK[birth.get(Calendar.DAY_OF_WEEK)] + "요일입니다.");
		// 따로 today를 셋팅하지 않으면 현재 날짜로 출력됨. 
		System.out.println("오늘(today)은 " + toString(today) 
                  + DAY_OF_WEEK[today.get(Calendar.DAY_OF_WEEK)] + "요일입니다.");

	// 두 날짜 간의 차이를 얻기 위해서, getTimeInMillis() 1/1000초 단위로 변환해야 함.     
   	long difference = 
            (today.getTimeInMillis() - birth.getTimeInMillis()) / 1000;
		System.out.println("그 날(birth)은 현재(today)까지 "
                               + difference + "초가 지났습니다.");
		System.out.println("일(day)로 계산하면 " + difference / (24 * 60 * 60) 
                               + "일 입니다."); // 1일 = 24(시간) * 60(분) * 60(초)
	}
	
	// toString() 메서드 생성하여 년,월,일 호출 되도록 함.    
	public static String toString(Calendar date) {
		return date.get(Calendar.YEAR)+"년 "+ (date.get(Calendar.MONTH)+1) 
                               + "월 " + date.get(Calendar.DATE) + "일 ";
	}
}

 

  • clear() 메서드
    - Calendar 객체의 모든 필드를 초기화함. 
     → 초기화된 값은 1970년 1월 1일 00:00:00 (0시 0분 0초) 으로 약속됨.
    - clear(int field) 메서드: Calendar 객체의 특정 필드를 초기화함.
// Calendar 객체 dt 생성 
Calendar dt = Calendar.getInstance();

// 현재 시간 반환됨.  
System.out.println(new Date(dt.getTimeInMillis()));

dt.clear(); // Calendar 객체의 모든 필드 초기화 
System.out.println(new Date(dt.getTimeInMillis())); // 1970년 1월 1일 00:00:00 반환

// 특정 필드만 초기화 하는 방법 
dt.clear(Calendar.SECOND);      // 초를 초기화 
dt.clear(Calendar.MINUTE);      // 분을 초기화 
dt.clear(Calendar.HOUR_OF_DAY); // 시간을 초기화 
dt.clear(Calendar.HOUR);        // 시간을 초기화

 

  • 다양한 메서드(method) 및 필드(field)의 관계
    - get(): 필드(field) 읽기
    - set(): 필드(field) 변경
    - clear(): 필드(field) 초기화
    - add(): 특정 필드(field) 값을 증가 or 감소시킴. (다른 필드에 영향을 줄 수 있음)  
    - roll(): 특정 필드(field) 값을 증가 or 감소시킴. (다른 필드에 영향을 줄 수 없음)  
Calendar date = Calendar.getInstance();
date.clear(); // 모든 필드(field) 초기화 
date.set(2023, 10, 30); // 2023년 11월 30일로 날짜 설정 

// add() 메서드의 경우, 다른 필드에 영향을 줌.
date.add(Calendar.DATE, 1);  // 날짜(DATE)에서 1을 더하면 2023년 12월 1일이 됨. (월도 바뀜)
date.add(Calendar.MONTH, -8) // 월(MONTH)에서 8을 빼면 2023년 3월 30일이 됨. 

// roll() 메서드의 경우, 다른 필드에 영향을 주지 않음. 
date.roll(Calendar.DATE, 1)  // 날짜(DATE)에서 1을 더하면 월은 바뀌지 않은 2023년 11월 1일이 됨.

 

  • 달력 만드는 방법 
    - 말일 구하기: (다음 달 1일) - (1일)
    - 1일의 요일 구하기 (1일이 일요일 이후인 경우, 빈 공간은 " " empty 처리 해줄 것)

  • Date 및 Calendar 간의 변환 
    - Date의 메서드는 대부분 deprecated 되었으나 여전히 사용되어지고 있음. (∵ Java는 하위 호환성이 좋기 때문에)
    - Calendar를 Date로 변환하는 방법 vs Date를 Calendar로 변환하는 방법
/* Calendar를 Date로 변환 */
Calendar cal = Calendar.getInstance();
// Date의 생성자 안에서 Calender 객체의 getTimeInMillis 메서드를 호출하여 Date 객체 d에 저장함. 
Date d = new Date(cal.getTimeInMillis());

/* Date를 Calendar로 변환 */ 
Date d = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(d); // setTime 메서드를 통해 Date 객체 호출하여 Calendar 객체 cal에 저장함.

 

java.time 패키지

  • 정의
    - Date와 Calendar의 단점을 개선한 새로운 클래스들을 제공함. (JDK 1.8 = JDK 8)
    - java.util.Date 및 java.util.Calendar의 경우에는 날짜와 시간을 항상 함께 다루어야 하는 단점이 있었음.
    - java.time의 경우, 날짜와 시간을 독립적으로 다룰 수 있도록 개선됨.

형식화 클래스

형식화 클래스

  • 정의
    - java.text 패키지의 DecimalFormat (10진수 숫자로 설정), SimpleDateFormat (날짜 형식화)
    - 숫자와 날짜를 원하는 형식으로 쉽게 출력하도록 함.
     → 숫자를 형식 문자열로, 혹은 날짜를 형식 문자열로 변환
    - 형식 문자열에서 숫자와 날짜를 뽑아내는 기능을 하기도 함. 
     → 형식 문자열을 숫자로, 혹은 형식 문자열을 날짜로 변환

DecimalFormat

  • 정의
    - 숫자를 형식화할 때 사용함.  (→ 숫자를 형식 문자열로 변환할 때)
    - 숫자 데이터를 정수, 부동소수점, 금액 등의 다양한 형식으로 표현할 수 있음. → parse(...);
    - (반대로) 일정한 형식의 텍스트 데이터 또한 숫자로 변환할 수 있음. → format(...);
double number = 1234567.89;

/* 숫자 형식화 */
DecimalFormat df = new DecimalFormat("#.#E0"); // 지수 기호 사용하여 지수 형식으로 나타냄.
String result = df.format(number); // number에 저장된 double 값을 문자열로 변환하여 result에 저장
// 결과: result = 1.2E6

/* 특정 형식의 문자열을 숫자로 변환 */
DecimalFormat df = new DecimalFormat("#,###.##"); // 1,234,567.89
Number num = df.parse("1,234,567.89");
double d = num.doubleValue();
// 결과: d = 1234567.89

 

cf. Number: 모든 숫자 wrapper 클래스의 최고 조상임.
cf. Integer.parseInt(): 콤마(,)가 포함된 문자열은 숫자로 변환 불가함.

  • 변환 시 사용하는 기호 및 의미, 패턴
기호 의미 패턴 결과(1234567.89)
0 10진수 (*값 없는 자릿수는 0으로 채움) 0
0.0
00000000.0000
1234568 (소수점 반올림하여 정수값만)
1234567.9 (소수점 첫번째 자리까지만)
001234567.8900 (빈자리 0으로 채움)
# 10진수 (값 없는 자리수 상관 없이 반환) #
#.#
########.####
1234568 (소수점 반올림하여 정수값만)
1234567.9 (소수점 첫번째 자리까지만)
1234567.89 (빈자리 그냥 넘김)
. 소수점 #.# 1234567.9 (소수점 첫번째 자리까지만)
- 음수 부호 #.#-
-#.#
1234567.89- (뒤에 음수 부호 붙이기)
-1234567.89 (앞에 음수 부호 붙이기)
, 단위 구분자 #,###.##
#,####.##
1,234,567.89 (뒤에서부터 단위 당 자리수 맞추기)
123,4567.89 (뒤에서부터 단위 당 자리수 맞추기)
E 지수 기호 #E0
0E0
##E0
...
.1E7
1E6 
1.2E6
...

 

 

SimpleDateFormat

  • 정의
    - 날짜와 시간을 다양한 형식으로 출력하도록 함.
    - 특정 형식으로 되어있는 문자열에서 날짜 및 시간을 출력해낼 수 있음.
  • 활용 방법
    - 원하는 출력 형식을 패턴을 작성하여 SimpleDateFormat 인스턴스를 생성함.

    - 출력하고자 하는 인스턴스를 가지고 format()을 통해 호출하면 지정된 출력 형식에 맞게 변환된 문자열을 반환 받을 수 있음.
// 숫자를 문자열로 변환하여 반환
Date today = new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
String result = df.format(today); // 오늘의 년,월,일을 문자열 형태로 변환하여 반환함.

// 문자열을 날짜 및 시간으로 변환하여 반환
DateFormat df1 = new StringDateFormat("yyyy년 MM월 dd일")
DateFormat df2 = new StringDateFormat("yyyy/MM/dd")
Date d = df1.parse("2023년 11월 23일"); // 문자열을 parse()를 사용하여 숫자데이터(Date)로 변환
String result = df2.format(d); // 숫자데이터(Date)를 format()을 사용하여 문자열로 변환

 

기호 의미
G 연대(BC, AD)
Y 년도
M 월 (1 ~ 12 or 1월 ~ 12월 or JAN ~ DEC)
w 의 몇 번째 주 (1 ~ 53)
W 의 몇 번째 주 (1 ~ 5)
D 의 몇 번째 일 (1 ~ 366)
d 의 몇 번째 일 (1 ~ 31)
F 월의 몇째 주 (몇 번째) 요일 (1 ~ 5)
E 요일
a 오전/오후 (AM/PM)
H 시간 (0 ~ 23)
k 시간 (1 ~ 24)
K 시간 (0 ~ 11)
h 시간 (1 ~ 12)
m 분 (0 ~ 59)
s 초 (0 ~ 59)
S 천분의 일초 (0 ~ 999)
z Time zone (General time zone) (ex. GMT +9:00)
Z Time zone (RFC 822 time zone)
' escape 문자 (특수문자를 표현하는데 사용)