[JAVA] 날짜와 시간

DongGyu Jung·2022년 2월 11일
0

자바(JAVA)

목록 보기
28/60
post-thumbnail

🏃‍♂️ 들어가기 앞서..

본 게시물은 스터디 활동 중에 작성한 게시물로 자바의 정석-기초편 교재를 학습하여 정리하는 글입니다.
※ 스터디 Page : 〔투 비 마스터 : 자바〕

*해당 교재의 목차 순서와 구성을 참고하여 작성하며
각 내용마다 부족할 수 있는 내용이나 개인적으로 궁금한 점은
추가적인 검색을 통해 채워나갈 예정입니다.



날짜와 시간을 다룬 클래스는 과거부터 다양하게 존재해오고 있다.
초기에는
Date클래스를 제공했지만
매우 빈약했고
이후,
새로운 Calendar클래스가 제공되었지만
몇 가지 단점들이 있었다.
( 두 클래스 모두 java.util 패키지 )

현재는
java.time패키지를 제공하며
기존 단점들을 개선한 클래스들을 사용할 수 있는데

여전히 이전 클래스들을 사용하고 있기 때문에
Calendar클래스와 Date클래스에 대해
알 필요가 있다.
(아쉽게도 java.time패키지에 대한 내용은 「자바의 정석-3판」에서 다룬다고 한다..)



📅 Calendar 클래스

Calendar클래스는
" 추상 클래스 "로

직접 객체를 생성하지 못해서
" getInstance()메서드 "를 통해
완전히 구현된 클래스의 인스턴스를 얻어야 한다.

Calendar cal = new Calendar(); // 에러발생

Calendar cal = Calendar.getInstance();

Calendar 클래스에는 다양한 버전의 달력이 구성되어 있다.

  • 서양력 : GregorianCalendar
  • 불교력 : BuddhistCalendar
  • 일본력

Calendar.getInstance() 메서드는
사용자의 시스템 정보를 읽어와
자동으로 적합한 달력 정보를 가지고 오는데


특정 역법 객체를 생성하도록 되어있으면
(ex. new GregorianCalendar(); 과 같은 객체 생성 으로 프로그램을 작성 )

다른 역법을 사용해야할 때,
클래스 전체적으로 수정이 필요하지만

메서드로 작성하면
메서드의 내용만 변경하면 되기 때문에
유지보수가 편리하다.


🎯 get 메서드

getInstance()를 통해 인스턴스를 생성하게 되면
기본적으로
" 현재 시스템의 날짜시간 정보가 담겨있다. "

정보를 가져올 때 get()메서드를 사용할 수 있는데

형식은
int get( int field )이다.

매개변수로 field값이 들어가게 된다.


◎ 날짜 필드

필드명설명
YEAR
MONTH월 ( 0부터 )
WEEK_OF_YEAR의 몇 번째
WEEK_OF_MONTH의 몇 번째
DATE
DAY_OF_MONTH의 몇 번째
DAY_OF_YEAR의 몇 번째
DAY_OF_WEEK요일( 1 ~ 7 _ 1 : 일요일 )
DAY_OF_WEEK_IN_MONTH의 몇 번째 요일

◎ 시간 필드

필드명설명
HOUR시간( 0~11 )
HOUR_OF_DAY시간( 0~23 )
MINUTE
SECOND
MILLISECOND1/1000 초
ZONE_OFFSETGMT 기준 시차 ( -12 ~ 12 )
AM_PM오전 / 오후

(※ 추가적인 field는 Java API 문서 참고)

getActualMaximum( Calendar.DATE ) : 이 달의 마지막 일


📝 set 메서드

get은 현재 사용자 시스템 정보를 불러온다면

set
날짜와 시간을 원하는 값으로 변경할 수 있다.

set메서드는
여러가지 오버로딩되어 있다.

void set(int field, int value) // 해당 field를 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) // 초 까지

/* 날짜 지정하기 */
Calendar date1 = Calendar.getInstance() ;

date1.set(2021, 7, 15) ; // 2021년 8월 15일 : 월 0부터 시작인 점 주의
// date1.set(Calendar.YEAR, 2017) ;
// date1.set(Calendar.MONTH, 7) ;
// date1.set(Calendar.DATE, 15) ;

/* 시간 지정하기 */
Calendar time1 = Calendar.getInstance() ;

// 10시 20분 30초
time1.set(Calendar.HOUR_OF_DAY, 10) ;
time1.set(Calendar.MINUTE, 20) ;
time1.set(Calendar.SECOND, 30) ;

getTimeInMillis() : 해당 시간의 1/1000 초 단위 시간

" 두 날짜간의 차이 " 를 구하는 경우,

( (이후 날짜).getTimeInMillis() - (이전 날짜).getTimeInMillis() ) / 1000
( milli second 단위이기 때문에 /1000을 해서 second 단위로 변환 )

: 초단위 값으로 차이를 구한 후, " 일(日) 단위 "로 변환 ( 24*60*60 )해서 사용해도 된다.

초단위 값에 대해
x시 y분 z초 형식으로 만들기 위해서는
" 큰 단위부터 '몫''나머지'를 활용해서 연산 "하면 편리하다.
( 단계별 단위값 계산하는 문제 유형에서 활요할 수 있다 : ex. 돈을 500원, 100원, 50원 동전별로 분류 )

import java.util.* ;
...
..
final int[] TIME_UNIT = {3600, 60, 1}; // " 큰단위 "부터 _ 시 - 분 - 초
final String[] TIME_UNIT_NAME = {"시간" , "분" , "초"};

Calendar time1 = Calendar.getInstance();
Calendar time2 = Calendar.getInstance();
.. //각 Calendar객체 값 지정
..

long diff = Math.abs(time1.getTimeInMillis() - time2.getTimeInMillis()) / 1000 ;
String tmp = "";
for(int i = 0; i < TIME_UNIT.length ; i++) {
	tmp += diff/TIME_UNIT[i] + UIME_UNIT_NAME[i] ; // x시간 - y분 - z초 순으로
    diff %= TIME_UNIT[i] // 나머지
}

🧺 clear 메서드

Calendar 객체 모든 필드 초기화
( EPOCH Time으로 : 1970년 1월 1일 00:00:00 )

Calendar dt = Calendar.getInstance() ; // 현재시간
System.out.println(new Date(dt.getTimeInMillis())) ; // Fri Feb 11 19:14:17 KST 2022

dt.clear() ; //초기화
System.out.println(new Date(dt.getTimeInMillis())) ; // Thu Jan 01 00:00:00 KST 1970

매개변수로
int field를 받을 수 있기 때문에
특정 필드 초기화를 할 수도 있다.

Calendar dt = Calendar.getInstance() ; // 현재시간
System.out.println(new Date(dt.getTimeInMillis())) ; // Fri Feb 11 19:14:17 KST 2022

dt.clear(Calendar.SECOND) ; // 초 초기화
dt.clear(Calendar.MINUTE) ; // 분 초기화
dt.clear(Calendar.HOUR_OF_DAY) ; // 시간(0~23) 초기화
dt.clear(Calendar.HOUR) ; // 시간(0~11) 초기화

System.out.println(new Date(dt.getTimeInMillis())) ; // Fri Feb 11 00:00:00 KST 2022

set() 날짜 시간을 변경하기 전에
" 차이를 더 정확하게 구하기 위해선 "
clear()메서드를 수행한 후,
작업하는 것이 좋다.


add 메서드

특정 필드의 값을 증가 / 감소 시키는 메서드
( 다른 필드에 영향 O _ ex. "분을 증가시키다가 '시'가 넘어가는 경우", "일을 증가시키다가 '월'이 넘어가는 경우 등 )

※ 형식 = add( int field, int amount )

Calendar date = Calendar.getInstance() ;
date.clear();
date.set(2022, 1, 28) ; // 2022년 2월 28일

date.add(Calendar.DATE, 1) ; // 날짜에 1 더함 -> 3월 1일로 넘어가는 경우
// add는 다른필드에 영향을 주기 때문에 MONTH는 2로 변경
date.add(Calendar.MONTH, -2) ; // 월에서 2를 뺌 -> 1월 1일

// 최종 결과 : 2022년 1월 1일

음수도 사용 가능

🧶 roll 메서드

특정 필드의 값을 증가 / 감소 시키는 메서드
( 다른 필드에 영향 X _ ex. 분을 증가시키다가 '시'가 넘어가도 '시' 변화 X, "일을 증가시키다가 '월'이 넘어가도 '월' 변화 X 등 )

※ 형식 = roll( int field, int amount )

Calendar date = Calendar.getInstance() ;
date.clear();
date.set(2022, 1, 28) ; // 2022년 2월 28일

date.roll(Calendar.DATE, 1) ; // 날짜에 1 더함 -> 3월 1일로 넘어가는 경우
// But, roll은 다른필드에 영향을 주지 않기 때문에 MONTH는 1로 유지
date.add(Calendar.MONTH, -2) ; // 월에서 2를 뺌 -> 2월 1일

// 최종 결과 : 2022년 12월 1일

< 예외 경우 >
필드가 " 말일 (end of month) "일 때,
" 필드가 바뀔 경우 "
일 필드에 영향이 미칠 수 있다.
( ex. 3월 31일에서 MONTH -1하면 2월 28일 이 되는 경우 )

음수도 사용 가능




Date - Calendar 변환

  • CalendarDate
Calendar cal = Calendar.getInstance();
...
Date d = new Date(cal.getTimeInMillis()) ; // " 1/1000 초단위 값 "으로 Date 인스턴스 생성

  • DateCalendar
Date d = new Date() ;
...
Calendar cal = Calendar.getInstance();
cal.setTime(d) ; // "Calendar 인스턴스 생성 후 " → " setTime 메서드 "로 세팅

0개의 댓글