Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 자바의 정석 기초편 ch1
- 코드로 시작하는 자바 첫걸음
- jpa - 객체지향 쿼리 언어
- 2024 정보처리기사 수제비 실기
- 스프링 고급 - 스프링 aop
- 스프링 mvc2 - 검증
- 자바의 정석 기초편 ch2
- 게시글 목록 api
- 스프링 mvc2 - 타임리프
- 자바의 정석 기초편 ch12
- 자바의 정석 기초편 ch4
- 스프링 mvc1 - 스프링 mvc
- 타임리프 - 기본기능
- 스프링 mvc2 - 로그인 처리
- @Aspect
- 자바의 정석 기초편 ch3
- 자바의 정석 기초편 ch7
- jpa 활용2 - api 개발 고급
- 자바의 정석 기초편 ch5
- 자바의 정석 기초편 ch6
- 스프링 db1 - 스프링과 문제 해결
- 스프링 mvc1 - 서블릿
- 자바의 정석 기초편 ch11
- 2024 정보처리기사 시나공 필기
- 스프링 입문(무료)
- 스프링 db2 - 데이터 접근 기술
- 자바의 정석 기초편 ch9
- 자바의 정석 기초편 ch14
- 자바의 정석 기초편 ch13
- 자바의 정석 기초편 ch8
Archives
- Today
- Total
나구리의 개발공부기록
자바의 정석 기초편 ch10 - 1 ~ 8[날짜와시간, calendar클래스, 예제풀이] 본문
유튜브 공부/JAVA의 정석 기초편(유튜브)
자바의 정석 기초편 ch10 - 1 ~ 8[날짜와시간, calendar클래스, 예제풀이]
소소한나구리 2023. 12. 7. 17:051) 날짜와 시간
(1) java.util.Date
- 날짜와 시간을 다룰 목적으로 만들어진 클래스 (JDK 1.0 - 1995년 말)
- Date의 메서드는 거의 deprecated(앞으로 사용하지 않을 것을 권장)되었지만 여전히 쓰이고 있음
(2) java.util.Calendar
- Date클래스를 개선한 새로운 클래스(JDK1.1 - 97년)
- 여전히 단점과 불편한점이 존재
(3) java.time패키지(해당 강의에서 다루지 않으므로 검색)
- Date와 Calendar의 단점을 개선한 새로운 클래스들을 제공(JDK1.8 - 2014년)
- Date와 Calendar는 항상 날짜와 시간을 함께 다뤘어야 했음
- Time에서는 분리해서 가능함
- LocalDate - 날짜만 다룸
- LocalTime - 시간만 다룸
- LocalDateTime - 동시에 다룸
2) Calendar클래스
- 추상 클래스이므로 getInstance()를 통해 구현된 객체를 얻어야 함
- 직접 new GregorianCalendar(); 생성을 하지 않는 이유는 구현객체의 변경이 있을 경우 메서드를 사용하는 곳에 모두 변경이 필요하기 때문임
(1) 캘린더 종류
- 서양력 - GregorianCalendar
- 불교력 - BuddhistCalendar
- 일본력 - JapaneseImperialCalendar
- 등등..
Calendar cal = new Calendar(); // 에러 -> 추상클래스는 인스턴스를 생성할 수 없다.
//getInstance()메서드는 Calendar클래스를 구현한 클래스의 인스턴스를 반환
Calendar cal = Calendar.getInstance();
(2) get()으로 날짜와 시간 필드 가져오기
Calendar cal = Calendar.getInstance(); // 현재 날짜와 시간으로 셋팅
int thisYear = cal.get(Calendar.YEAR); // 올해가 몇년인지 반환
int lastDayOfMonth = cal.getActualMaximum(Calendar.DATE); // 이 달의 마지막날을 반환
(3) Calendar에 정의된 필드
- get(Calendar.필드명)으로 원하는 값을 가져올 수 있음
구분 | 필드명 | 설명 |
날짜 | YEAR | 년 |
MONTH | 월 (0부터 시작 주의) / 0 입력 -> 1, 7 입력 -> 8 | |
WEEK_OF_YEAR | 그 해의 몇 번째 주 | |
WEEK_OF_MONTH | 그 달의 몇 번째 주 | |
DATE | 일 | |
DAY_OF_MONTH | 그 달의 몇 번째 일 | |
DAY_OF_YEAR | 그 해의 몇 번째 일 | |
DAY_OF_WEEK | 요일 (1 ~ 7) / 1: 일요일 ... 7: 토요일 | |
DAY_OF_WEEK_IN_MONTH | 그 달의 몇 번째 요일 | |
시간 | HOUR | 시간 (0~11) |
HOUR_OF_DAY | 시간 (0~23) | |
MINUTE | 분 | |
SECOND | 초 | |
MILLISECOND | 천분의 일초 | |
ZONE_OFFSET | GMT기준 시차(천분의 일초 단위) / 한국은 +9 | |
AM_PM | 오전/오후 |
(4) 예제 - get()
import java.util.*;
class Ex10_1 {
public static void main(String[] args) {
// 기본적으로 현재날짜와 시간으로 설정됨. - Calendar객체 생성
Calendar today = Calendar.getInstance();
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));
System.out.println("요일(1~7, 1:일요일): "
+ today.get(Calendar.DAY_OF_WEEK)); // 1:일요일, 2:월요일, ... 7:토요일
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) ); // 이 달의 마지막 일을 찾음
}
}
/*
출력값
이 해의 년도 : 2023
월(0~11, 0:1월): 11
이 해의 몇 째 주: 49
이 달의 몇 째 주: 2
이 달의 몇 일: 7
이 달의 몇 일: 7
이 해의 몇 일: 341
요일(1~7, 1:일요일): 5
이 달의 몇 째 요일: 1
오전_오후(0:오전, 1:오후): 1
시간(0~11): 2
시간(0~23): 14
분(0~59): 31
초(0~59): 0
1000분의 1초(0~999): 215
TimeZone(-12~+12): 9
이 달의 마지막 날: 31
*/
(5) 예제 - 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)
// 날짜를 한번에 설정
Calendar date1 = Calendar.getInstance();
date1.set(2017,7,15); // 2017년 8월 15일 (월은 0부터 시작 주의!)
// 날짜를 특정 필드값만 설정 할 수 있음
date1.set(Calendar.YEAR, 2017);
date1.set(Calendar.MONTH,7);
date1.set(Calendar.DATE, 15);
// 시간 지정하는 방법 - Calendar 클래스에는 시간만 지정하는 방법이 없어서 하나씩 설정
Calendar Time1 = Calendar.getInstance();
Time1.set(Calendar.HOUR_OF_DAY, 10); // time1을 10시 20분 30초로 설정
Time1.set(Calendar.MINUTE, 20);
Time1.set(Calendar.SECOND, 30);
(6) 날짜변경 예제
- getTimeInMillis()메서드: 시간을 밀리초 단위로 변경
- 날짜, 시간 계산을 하기 위해서는 계산을 위해서 초로 변환 하여 계산
- getTimeInMillis()메서드 활용해서 밀리초 단위로 변경 뒤 계산이 완료된 값에 /1000 연산을 하여 초단위로 복귀하여 반환
- 초단위를 표현하고자 하는 값(년, 월, 일, 시 등등)으로 변환 (일단위로 변환하는 식: 구한값(초)/24*60*60)
import java.util.*;
class Ex10_2 {
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(2019, 3, 29); // 2019년 4월 29일로 날짜를 설정
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() 천분의 일초 단위로 변환할 경우 마지막에 /1000를 해줘야 초단위로 변환 됨
long difference =
(date2.getTimeInMillis() - date1.getTimeInMillis())/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) + "일 ";
}
}
/*
출력 결과
date1은 2019년 4월 29일 월요일이고,
오늘(date2)은 2023년 12월 7일 목요일입니다.
그 날(date1)부터 지금(date2)까지 145411200초가 지났습니다.
일(day)로 계산하면 1683일입니다.
*/
(7) 시간변환예제
- 초를 시, 분, 초로 변환
- 시간계산시에는 음수가 나올 수 있으므로 계산 결과를 절대값으로 반환하도록 하는 것을 권장함
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, 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);
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 + "입니다.");
}
}
/*
출력값
time1 :10시 20분 30초
time2 :20시 30분 10초
time1과 time2의 차이는 36580초 입니다.
*/
시분초로 변환하면 10시간 9분 40초 입니다.
(8) clear()
- Calendar객체의 모든 필드를 초기화 - 1970년 1월 1일 00:00:00으로 초기화 됨
- clear(int field): 메서드의 인자값으로 필드를 입력하여 특정 필드를 초기화 할 수 있음
- Calendar객체를 생성 후 set메서드로 값을 입력할 경우 clear()로 초기화를 해준 후 입력을해야 날짜 계산이 정확함
(9) clear 예제
- clear()를 사용하여 오차를 없앰
import java.util.Calendar;
class Ex10_5 {
static int getDayDiff(String yyyymmdd1, String yyyymmdd2) {
int diff = 0;
try {
int year1 = Integer.parseInt(yyyymmdd1.substring(0, 4));
int month1 = Integer.parseInt(yyyymmdd1.substring(4, 6)) - 1;
int day1 = Integer.parseInt(yyyymmdd1.substring(6, 8));
int year2 = Integer.parseInt(yyyymmdd2.substring(0, 4));
int month2 = Integer.parseInt(yyyymmdd2.substring(4, 6)) - 1;
int day2 = Integer.parseInt(yyyymmdd2.substring(6, 8));
Calendar date1 = Calendar.getInstance();
Calendar date2 = Calendar.getInstance();
// 객체생성 - 약간 밀리세컨드 차이가 발생
// 오차를 지우기 위해서 clear(); 호출
date1.clear();
date2.clear();
date1.set(year1, month1, day1);
date2.set(year2, month2, day2);
System.out.println((date1.getTimeInMillis()
- date2.getTimeInMillis()) / (24*60*60*1000f));
diff = (int)((date1.getTimeInMillis()
- date2.getTimeInMillis()) / (24*60*60*1000));
} catch (Exception e) {
diff = 0;
}
return diff;
}
public static void main(String[] args) {
System.out.println(getDayDiff("20010103", "20010101")); // 2가 나와야함
System.out.println(getDayDiff("20010103", "20010103")); // 0
System.out.println(getDayDiff("20010103", "200103"));
}
}
/*
clear() 전 출력결과 -> 오차 발생
1.9999998 -> 실수값이 출력
1 -> 2가 나와야함
0.0
0
0
clear() 후 출력 결과 -> 오차가 없음
2.0
2
0.0
0
0
*/
(10) add()와 roll()의 차이
- add(): 특정 필드의 값을 증가 또는 감소 - 다른 필드에 영향O
- roll(): add()와 같지만 다른 필드에 영향X
Calendar date = Calendar.getInstance();
date.clear(); // 모든 필드 초기화
date.set(2020,7,31); // 2020년 8월 31일로 설정
add() -> 값이 변함으로 인해 다른 필드가 변경 됨
date.add(Calendar.DATE, 1); // 날짜에 1을 더함 -> 9월 1일
date.add(Calendar.MONTH, -8); // 9월 1일 에서 8월을 뺌 -> 1월 1일
date.clear(); // 모든 필드 초기화
date.set(2020,7,31); // 2020년 8월 31일로 설정
roll() -> 값이 변해도 다른 필드는 변동 없음
date.roll(Calendar.DATE, 1); // 날짜에 1을 더함 -> 8월 1일
date.roll(Calendar.MONTH, -8); // 월에서 8을 뺌 -> 2020년 12월 1일이 됨
// 만일 add()일 경우 2019년 12월 1일이 됨
(11) 예제
import java.util.*;
class Ex10_4 {
public static void main(String[] args) {
Calendar date = Calendar.getInstance();
date.set(2019, 7, 31); // 2019년 8월 31일
System.out.println(toString(date));
System.out.println("= 1일 후 =");
date.add(Calendar.DATE, 1);
System.out.println(toString(date));
System.out.println("= 6달 전 =");
date.add(Calendar.MONTH, -6);
System.out.println(toString(date));
System.out.println("= 31일 후(roll) =");
date.roll(Calendar.DATE, 31);
System.out.println(toString(date));
System.out.println("= 31일 후(add) =");
date.add(Calendar.DATE, 31);
System.out.println(toString(date));
}
// 년 월 일을 보기좋게 출력하기위해 toString()를 오버라이딩
public static String toString(Calendar date) {
return date.get(Calendar.YEAR)+"년 "+ (date.get(Calendar.MONTH)+1)
+"월 " + date.get(Calendar.DATE) + "일";
}
}
/*
출력결과
2019년 8월 31일
= 1일 후 =
2019년 9월 1일
= 6달 전 =
2019년 3월 1일
= 31일 후(roll) =
2019년 3월 1일
= 31일 후(add) =
2019년 4월 1일
*/
(12) 달력출력하기 예제
import java.util.*;
class Ex10_5 {
public static void main(String[] args) {
if(args.length !=2) {
System.out.println("Usage : java Ex10_5 2019 9");
return;
}
int year = Integer.parseInt(args[0]); // 2019
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을 빼주어야 함
// 예를 들어, 2019년 11월 1일은 sDay.set(2019, 10, 1);과 같이 해줘야 함
sDay.set(year, month-1, 1); // month는 0부터 시작
eDay.set(year, month, 1);
// 다음달의 첫날(12월 1일)에서 하루를 빼면 현재달의 마지막 날(11월 30일)이 됨
eDay.add(Calendar.DATE, -1);
// 첫 번째 요일이 무슨 요일인지 알아냄
START_DAY_OF_WEEK = sDay.get(Calendar.DAY_OF_WEEK);
// eDay에 지정된 날짜를 얻어옴
END_DAY = eDay.get(Calendar.DATE);
System.out.println(" " + args[0] +"년 " + args[1] +"월");
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();
}
}
}
/*
출력결과
2019년 9월
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
*/
(13) Date와 Calendar간의 변환
- Date를 여전히 사용 하고 있으므로 알고 있는것이 좋음
// Calendar를 Date로 변환
Calendar cal = Calendar.getInstance();
Date d = new Date(cal.getTimeInMillis());
// Date를 Calendar로 변환
Date d = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(d)
** 출처 : 남궁성의 정석코딩_자바의정석_기초편 유튜브 강의