//[10-1] Calendar클래스와 SimpleDateFormat클래스를 이용해서
// 2010년의 매월 두 번째 일요일의 날짜를 출력하시오.
/*
<실행결과>
2010-01-10은 2번째 일요일입니다.
2010-02-14은 2번째 일요일입니다.
2010-03-14은 2번째 일요일입니다.
2010-04-11은 2번째 일요일입니다.
2010-05-09은 2번째 일요일입니다.
2010-06-13은 2번째 일요일입니다.
2010-07-11은 2번째 일요일입니다.
2010-08-08은 2번째 일요일입니다.
2010-09-12은 2번째 일요일입니다.
2010-10-10은 2번째 일요일입니다.
2010-11-14은 2번째 일요일입니다.
2010-12-12은 2번째 일요일입니다.
*/
<풀이접근1>💡 일정한 형식으로 반복되는 날짜를 계산하고 싶을 때는 Calendar 클래스의 add(속성, 증감값)를 사용하는 것이 좋다. 💡 이럴 때는 그 기준이 존재해야 한다. 보통 처음 그 해 연도의 1월 1일으로 세팅하고 add를 통해서 일정 값을 증감시켜 주는 것이 필요하다.
<접근방식1>
❌❌❌❌❌❌❌
public static void main(String[] args) {
// 달력 객체 생성하여 cal에 저장, SimpleDateFormat객체 생성하여 df에 저장
Calendar cal = Calendar.getInstance();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); //⭐MM이 달이고 mm이 분이다. 헷갈리지 말자!
cal.set(2010,00,1); //⭐ cal객체의 달력을 2010년 01월 01일로 맞춤.
System.out.println(cal);
for (int i=1; i<=7; i++) {
if(cal.get(Calendar.DAY_OF_WEEK)== Calendar.SUNDAY) { //⭐순회해서 DAY_OF_WEEK 값이 일요일이면 for문 끝냄.
break; //return이 아니라 break를 써야 main메서드를 탈출하는 것이 아닌 for문을 탈출함.
}
cal.add(Calendar.DAY_OF_MONTH, 1); //⭐날짜를 하루씩 증가시키면서 일요일 찾기
}
//⭐ 2010년 1월의 첫 번째 일요일이 cal에 저장된 상태에서 두 번째 일요일을 구하려면 날짜를 +7 해주고, 각 개월의 두 번째 일요일을 구하려면 거기서 ~~+31해야한다.~~ ⭐⭐아니다. 모든 일수가 동일하지 않기때문에 달을+1한다.
cal.add(Calendar.DAY_OF_MONTH, 7); //⭐ 1월의 두 번째 일요일
System.out.println(cal);
for(int month=0; month<12; month++) {
System.out.printf(df.format(cal.getTime())+"은 %d번째 %d요일입니다.%n", cal.get(Calendar.DAY_OF_WEEK_IN_MONTH), cal.get(Calendar.DAY_OF_WEEK));
cal.add(Calendar.MONTH, 1); //⭐한 달씩 증가.❌❌❌ 요일까지 맞춰 증가하는게 아니다
}
}
<해당코드 실행결과>
2010-01-10은 2번째 1요일입니다.
2010-02-10은 2번째 4요일입니다.
2010-03-10은 2번째 4요일입니다.
2010-04-10은 2번째 7요일입니다.
2010-05-10은 2번째 2요일입니다.
2010-06-10은 2번째 5요일입니다.
2010-07-10은 2번째 7요일입니다.
2010-08-10은 2번째 3요일입니다.
2010-09-10은 2번째 6요일입니다.
2010-10-10은 2번째 1요일입니다.
2010-11-10은 2번째 4요일입니다.
2010-12-10은 2번째 6요일입니다.
❌❌❌❌❌❌❌
class Sol_Exercise10_1 {
public static void main(String[] args) {
// 달력 객체 생성하여 cal에 저장, SimpleDateFormat객체 생성하여 df에 저장
Calendar cal = Calendar.getInstance();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); //⭐MM이 달이고 mm이 분이다. 헷갈리지 말자!
cal.set(2010,00,1); //⭐ cal객체의 달력을 2010년 01월 01일로 맞춤.
//while(cal.get(Calendar.MONTH)<11) { //❗❗무한 루프 때문에 사용불가 (Month에서 11+1=0이 되버린다.)
int month=1; //⭐ 무한루프 방지용 변수
while(true) {
cal.add(Calendar.DAY_OF_MONTH, 1); // 날짜를 1씩 증가시켜서
if(cal.get(Calendar.DAY_OF_WEEK)== Calendar.SUNDAY) { //⭐ cal객체의 요일이 일요일이면
cal.add(Calendar.DAY_OF_MONTH, 7); // 일주일 증가시키면 두 번째 일요일.
System.out.printf("%s은 %d번째 일요일입니다.%n",
df.format(cal.getTime()),
cal.get(Calendar.DAY_OF_WEEK_IN_MONTH)); //값을 출력하고
cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH)+1, 1); //⭐다음 달 1일로 초기화 ⭐⭐단, MONTH가 11일때 +1하게 되면 =>0로 바뀐다. (무한루프주의)
month++; //⭐ 무한루프 방지용 변수
if (month>12) { //⭐ 무한루프 방지
break;
}
}
}
}
}
<답안>
2010-01-10은 2번째 일요일입니다.
2010-02-14은 2번째 일요일입니다.
2010-03-14은 2번째 일요일입니다.
2010-04-11은 2번째 일요일입니다.
2010-05-09은 2번째 일요일입니다.
2010-06-13은 2번째 일요일입니다.
2010-07-11은 2번째 일요일입니다.
2010-08-15은 3번째 일요일입니다.
2010-09-12은 2번째 일요일입니다.
2010-10-10은 2번째 일요일입니다.
2010-11-14은 2번째 일요일입니다.
2010-12-12은 2번째 일요일입니다.
import java.util.*;
import java.text.*;
class Exercise10_1
{
public static void main(String[] args)
{
Calendar cal = Calendar.getInstance();
cal.set(2010,0,1); // cal의 날짜를 2010년 1월 1일로 설정한다.
for(int i=0; i < 12;i++) {
int weekday = cal.get(Calendar.DAY_OF_WEEK); // 1일의 요일을 구한다.
// ⭐두 번째 일요일은 1일의 요일에 따라 달라진다.
// ⭐1일이 일요일인 경우에는 두번째 일요일은 8일이고,
// ⭐1일이 다른 요일일 때는 16에서 1일의 요일(weekday)을 빼면 알 수 있다.
int secondSunday = (weekday==1) ? 8 : 16 - weekday;
// 두 번째 일요일(secondSunday)로 cal의 날짜(DAY_OF_MONTH)를 바꾼다.
cal.set(Calendar.DAY_OF_MONTH, secondSunday);
Date d = cal.getTime(); // Calendar를 Date로 변환한다.
System.out.println(new SimpleDateFormat("yyyy-MM-dd은 F번째 E요일입니다.").format(d));
// 날짜를 다음달 1일로 변경한다.
cal.add(Calendar.MONTH, 1);
cal.set(Calendar.DAY_OF_MONTH,1);
}
}
}
int secondSunday = (weekday==1) ? 8 : 16 - weekday;
// 두 번째 일요일(secondSunday)로 cal의 날짜(DAY_OF_MONTH)를 바꾼다. cal.set(Calendar.DAY_OF_MONTH, secondSunday);
Date d = cal.getTime(); // Calendar를 Date로 변환한다.
System.out.println(new SimpleDateFormat("yyyy-MM-dd은
F번째 E요일입니다.").format(d)); //⭐F번째 E요일 기호 사용
new SimpleDateFormat(패턴문자열)
객체에 패턴을 지정하고 바로 format(Date d)
메서드를 활용해 형식화 해버릴 수 있다.new SimpleDateFormat("yyyy-MM-dd은 F번째 E요일입니다.").format(d)
//[10-2] 어떤 회사의 월급날이 매월 21일이다. 두 날짜 사이에 월급날이 몇 번있는지 계산해서 반환하는 메서드를 작성하고 테스트 하시오.
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
class Exercise10_2 {
static int paycheckCount(Calendar from, Calendar to) {
/*
(1) 아래의 로직에 맞게 코드를 작성하시오.
1. from 또는 to가 null이면 0을 반환한다.
2. from와 to가 같고 날짜가 21일이면 1을 반환한다.
3. to와 from이 몇 개월 차이인지 계산해서 변수 monDiff에 담는다.
4. monDiff가 음수이면 0을 반환한다.
5. 만일 from의 일(DAY_OF_MONTH)이 21일이거나 이전이고
to의 일(DAY_OF_MONTH)이 21일이거나 이후이면 monDiff의 값을 1 증가시킨다.
6. 만일 from의 일(DAY_OF_MONTH)이 21일 이후고
to의 일(DAY_OF_MONTH)이 21일 이전이면 monDiff의 값을 1 감소시킨다.
*/
return monDiff;
}
static void printResult(Calendar from, Calendar to) {
Date fromDate = from.getTime();
Date toDate = to.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
System.out.print(sdf.format(fromDate)+" ~ "
+sdf.format(toDate)+":"); System.out.println(paycheckCount(from, to));
}
public static void main(String[] args) { Calendar fromCal = Calendar.getInstance(); Calendar toCal = Calendar.getInstance();
fromCal.set(2010,0,1); toCal.set(2010,0,1); printResult(fromCal, toCal);
fromCal.set(2010,0,21); toCal.set(2010,0,21); printResult(fromCal, toCal);
fromCal.set(2010,0,1); toCal.set(2010,2,1); printResult(fromCal, toCal);
fromCal.set(2010,0,1); toCal.set(2010,2,23); printResult(fromCal, toCal);
fromCal.set(2010,0,23); toCal.set(2010,2,21); printResult(fromCal, toCal);
fromCal.set(2011,0,22); toCal.set(2010,2,21); printResult(fromCal, toCal);
}
}
/*
<실행결과>
2010-01-01 ~ 2010-01-01:0
2010-01-21 ~ 2010-01-21:1
2010-01-01 ~ 2010-03-01:2
2010-01-01 ~ 2010-03-23:3
2010-01-23 ~ 2010-03-21:2
2011-01-22 ~ 2010-03-21:0
*/
class Sol_Exercise10_2 {
static int paycheckCount(Calendar from, Calendar to) {
/*
(1) 아래의 로직에 맞게 코드를 작성하시오.
1. from 또는 to가 null이면 0을 반환한다.
2. from와 to가 같고 날짜가 21일이면 1을 반환한다.
3. to와 from이 몇 개월 차이인지 계산해서 변수 monDiff에 담는다.
4. monDiff가 음수이면 0을 반환한다.
5. 만일 from의 일(DAY_OF_MONTH)이 21일이거나 이전이고
to의 일(DAY_OF_MONTH)이 21일이거나 이후이면 monDiff의 값을 1 증가시킨다.
6. 만일 from의 일(DAY_OF_MONTH)이 21일 이후고
to의 일(DAY_OF_MONTH)이 21일 이전이면 monDiff의 값을 1 감소시킨다.
*/
if(from==null || to==null) return 0; // null값이 아니어야 함
if(from==to && from.get(Calendar.DAY_OF_MONTH)==21) return 1; //Date가 같고 일자가 21이면 1 반환
int monDiff = (int)((to.getTimeInMillis()-from.getTimeInMillis())/(1000*60*60*24*30)); //->s->m->h->day->month ⭐그러나 month는 항상 30일인것이 아니다.
System.out.println(monDiff);
if(monDiff<0) return 0; //to가 from보다 이전일이면 0을 반환
if((from.get(Calendar.DAY_OF_MONTH)<=21)&&(to.get(Calendar.DAY_OF_MONTH)>=21)) monDiff++;
if((from.get(Calendar.DAY_OF_MONTH)>21)&&(to.get(Calendar.DAY_OF_MONTH)<21)) monDiff--;
return monDiff;
}
static void printResult(Calendar from, Calendar to) {
Date fromDate = from.getTime();
Date toDate = to.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
System.out.print(sdf.format(fromDate)+" ~ "
+sdf.format(toDate)+":"); System.out.println(paycheckCount(from, to));
}
public static void main(String[] args) { Calendar fromCal = Calendar.getInstance(); Calendar toCal = Calendar.getInstance();
fromCal.set(2010,0,1); toCal.set(2010,0,1); printResult(fromCal, toCal);
fromCal.set(2010,0,21); toCal.set(2010,0,21); printResult(fromCal, toCal);
fromCal.set(2010,0,1); toCal.set(2010,2,1); printResult(fromCal, toCal);
fromCal.set(2010,0,1); toCal.set(2010,2,23); printResult(fromCal, toCal);
fromCal.set(2010,0,23); toCal.set(2010,2,21); printResult(fromCal, toCal);
fromCal.set(2011,0,22); toCal.set(2010,2,21); printResult(fromCal, toCal);
}
}
<결과값>
2010-01-01 ~ 2010-01-01:0
0
2010-01-21 ~ 2010-01-21:0
1
2010-01-01 ~ 2010-03-01:-2
0
2010-01-01 ~ 2010-03-23:-4
0
2010-01-23 ~ 2010-03-21:-2
0
2011-01-22 ~ 2010-03-21:15
15
문제 접근:
원래 ⭐두 시간의 차를 구할 때 Calendar.getTimeInMillis()
의 차이를 이용했다. ⭐그러나 이 방식대로는 최대 단위 '일'까지만 정확히 환산할 수 있다. (차이의 ms)/(1000초*60분*60시간*24일)
왜냐하면 한 달은 최소 28일부터 최대31일까지 다양하기 때문이다.
⭐ 따라서 두 시간의 차이를 '월' 단위에서 구하려면
💡from과 to의 연, 월을 따로 구하여 연*12+월
의 시간차를 구하자!
또한 5~6번에서 사용될 일자간 비교에서는 to의 일자와 from의 일자를 각각 구하여 따로 비교해주면 된다.
문제 풀이 :
class Sol_Exercise10_2 {
static int paycheckCount(Calendar from, Calendar to) {
/*
(1) 아래의 로직에 맞게 코드를 작성하시오.
1. from 또는 to가 null이면 0을 반환한다.
2. from와 to가 같고 날짜가 21일이면 1을 반환한다.
3. to와 from이 몇 개월 차이인지 계산해서 변수 monDiff에 담는다.
4. monDiff가 음수이면 0을 반환한다.
5. 만일 from의 일(DAY_OF_MONTH)이 21일이거나 이전이고
to의 일(DAY_OF_MONTH)이 21일이거나 이후이면 monDiff의 값을 1 증가시킨다.
6. 만일 from의 일(DAY_OF_MONTH)이 21일 이후고
to의 일(DAY_OF_MONTH)이 21일 이전이면 monDiff의 값을 1 감소시킨다.
*/
if(from==null || to==null) return 0; //1. null값이 아니어야 함
if(from==to && from.get(Calendar.DAY_OF_MONTH)==21) return 1; //2. Date가 같고 일자가 21이면 1 반환, eqauls()를 사용하여도 됨.
//3.monDiff와 5~6에 사용할 변수 만들기
int toYear = to.get(Calendar.YEAR);
int toMon = to.get(Calendar.MONTH);
int toDay = to.get(Calendar.DAY_OF_MONTH);
int fromYear = from.get(Calendar.YEAR);
int fromMon = from.get(Calendar.MONTH);
int fromDay = from.get(Calendar.DAY_OF_MONTH);
int monDiff = (toYear*12+toMon) - (fromYear*12+fromMon);
//4.
if (monDiff<0) return 0;
//5~6.
if (fromDay<=21&&toDay>=21) monDiff++;
if (fromDay>21&&toDay<21) monDiff--;
return monDiff;
}
static void printResult(Calendar from, Calendar to) {
Date fromDate = from.getTime();
Date toDate = to.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
System.out.print(sdf.format(fromDate)+" ~ "
+sdf.format(toDate)+":"); System.out.println(paycheckCount(from, to));
}
public static void main(String[] args) { Calendar fromCal = Calendar.getInstance(); Calendar toCal = Calendar.getInstance();
fromCal.set(2010,0,1); toCal.set(2010,0,1); printResult(fromCal, toCal);
fromCal.set(2010,0,21); toCal.set(2010,0,21); printResult(fromCal, toCal);
fromCal.set(2010,0,1); toCal.set(2010,2,1); printResult(fromCal, toCal);
fromCal.set(2010,0,1); toCal.set(2010,2,23); printResult(fromCal, toCal);
fromCal.set(2010,0,23); toCal.set(2010,2,21); printResult(fromCal, toCal);
fromCal.set(2011,0,22); toCal.set(2010,2,21); printResult(fromCal, toCal);
}
}
/*
<실행결과>
2010-01-01 ~ 2010-01-01:0
2010-01-21 ~ 2010-01-21:1
2010-01-01 ~ 2010-03-01:2
2010-01-01 ~ 2010-03-23:3
2010-01-23 ~ 2010-03-21:2
2011-01-22 ~ 2010-03-21:0
*/
String data = "123,456,789.5"; //data :123,456,789.5
System.out.println("data :" + data);
DecimalFormat df1 = new DecimalFormat("###,###.#");
Number d = df1.parse(data); //⭐data의 형식문자열을 Number d로 내장된 패턴에 의거해 parse
System.out.println("d :"+ d); //⭐d :1.234567895E8
//❓ parse 되었을 때 자동으로 지수표현이 붙는건가?
⭐Number클래스에는 지수부가 붙는구나!
double d = num.doubleValue();
를 사용하면 d의 값이 1.234567895E8
가 아니라 123456789.5
가 된다.//[10-4] 화면으로부터 날짜를 “2007/05/11”의 형태로 입력받아서 무슨 요일인지 출력하 는 프로그램을 작성하시오.
//단, 입력된 날짜의 형식이 잘못된 경우 메세지를 보여주고 다시 입력받아야 한다.
/*
<실행결과>
날짜를 yyyy/MM/dd의 형태로 입력해주세요.(입력예:2007/05/11)
>>2009-12-12
날짜를 yyyy/MM/dd의 형태로 입력해주세요.(입력예:2007/05/11)
>>2009/12/12
입력하신 날짜는 토요일입니다.
*/
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
class Sol_Exercise10_4 {
static Scanner sc = new Scanner(System.in);
static void dataProces() throws ParseException { //⭐ ParseException을 메인으로 넘겨줘서 처리하게 하는 이유? 잘못된 값을 입력받으면 다시 받을 수 있도록!
System.out.println("날짜를 yyyy/MM/dd의 형태로 입력해주세요.(입력예:2007/05/11)");
String input = sc.nextLine();
//⭐ 일회용 객체를 생성하여 parse로 바로 Date화 함.
Date date = new SimpleDateFormat("yyyy/MM/dd").parse(input); //⭐ParseException 발생가능
//⭐ Date 클래스 기능을 다시 형식화 하려면 SimpleDateFormat 객체가 필요하다.
DateFormat df = new SimpleDateFormat("입력하신 날짜는 E요일 입니다.");
System.out.println(df.format(date));
}
public static void main(String[] args) {
while(true) {
try {
dataProces();
break;//⭐ 출력이 정상적으로 완료되면 메서드를 끝내야 한다.
} catch (ParseException e) {
continue;
}
}
}
}
class Exercise10_5 {
/*
(1) getDayDiff메서드를 작성하시오.
*/
static int getDayDiff(String yyyymmdd1, String yyyymmdd2) {
Date d1 = null;
Date d2 = null;
try {
d1 = new SimpleDateFormat("yyyyMMdd").parse(yyyymmdd1);
d2 = new SimpleDateFormat("yyyyMMdd").parse(yyyymmdd2);
} catch (ParseException e) {
//⭐주어진 문자열이 유효하지 않으면 0을 반환 (⭐⭐예외를 이 메서드에서 해결함)
return 0;
}
// ⭐각 Date를 getTimeInMills()로 나타내서 차이를 구하기 위해 Calendar화
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
c1.setTime(d1);
c2.setTime(d2);
return (int)((c1.getTimeInMillis()-c2.getTimeInMillis())/(1000*60*60*24));
}
public static void main(String[] args){
System.out.println(getDayDiff("20010103","20010101"));
System.out.println(getDayDiff("20010103","20010103"));
System.out.println(getDayDiff("20010103","200103"));
}
}
<실행결과>
2
0
0
⭐⭐ 예외를 메서드 안에서 해결하기를 선택했다. 10-5와 비교가 가능하다.
모범답안
import java.util.*;
class Exercise10_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();
date1.set(year1, month1, day1);
date2.set(year2, month2, day2);
diff = (int)((date1.getTimeInMillis()-date2.getTimeInMillis())
/(24*60*60*1000));
} catch(Exception e) {
diff = 0; // substring(), parseInt()에서 예외가 발생하면 0을 반환한다.
}
return diff;
}
public static void main(String[] args){
System.out.println(getDayDiff("20010103","20010101"));
System.out.println(getDayDiff("20010103","20010103"));
System.out.println(getDayDiff("20010103","200103"));
}
}
/*
[해설] 넘겨받은 문자열을 substring()으로 잘라서 년, 월, 일을 각각 구한 다음,
이 값들을 가지고 Calendar의 년월일을 설정한다.
[참고] Calendar클래스의 month값은 1이 아닌 0부터 시작하기 때문에 1을 빼주어야 한다.
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));
Calendar date1 = Calendar.getInstance(); date1.set(year1, month1, day1);
Calendar의 getTimeInMillis()는 날짜를 천분의 일초단위로 변환해서 반환한다. getTime
Millis()를 이용해서 두 날짜를 천분의 일초로 변환해서 차이를 구한 다음에 일(day) 단 위로 변환하면 두 날짜의 날(day) 차이를 구할 수 있다.
천분의 일초 단위를 일 단위로 바꾸려면 24*60*60*1000로 나눠주면 된다.
(1일 = 24시간 = 24*60분 = 24*60*60초 = 24*60*60*1000밀리세컨드)
date1.set(year1, month1, day1); date2.set(year2, month2, day2);
diff = (int)((date1.getTimeInMillis()-date2.getTimeInMillis())
/(24*60*60*1000));
*/
//[10-6] 자신이 태어난 날부터 지금까지 며칠이 지났는지 계산해서 출력하시오.
/*
<실행결과>
birth day=2000-01-01
today =2016-01-29
5872 days
*/
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
class Sol_Exercise10_6 {
public static void main(String[] args) throws ParseException {
String birth = "2000-01-01";
String today = "2016-01-29";
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
Date dateBirth = df.parse(birth);
Date dateToday = df.parse(today);
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
c1.setTime(dateBirth);
c2.setTime(dateToday);
//⭐ 며칠이 지났는지는 getTimeInMills()의 차이를 통해 구할 수 있다.
long diff = ((c2.getTimeInMillis()-c1.getTimeInMillis())/(1000*60*60*24)); // 1995-10-27 ⭐ms는 초,분,시,일로 반드시 나누어 떨어짐.
System.out.println(
"birthday="+birth+"\n"+
"today="+today+"\n"+
diff+"days");
}
}
💡java.time 패키지의 LocalDate 이용하기
import java.time.*;
import java.time.temporal.*;
class Exercise10_6 {
public static void main(String[] args) {
LocalDate birthDay = LocalDate.of(2000, 1, 1); // 자신의 생일을 지정
LocalDate now = LocalDate.now();
long days = birthDay.until(now, ChronoUnit.DAYS);
System.out.println("birth day="+birthDay); System.out.println("today ="+now); System.out.println(days +" days");
}
}
<// [10-7] 2016년 12월 네번째 화요일의 날짜를 아래의 실행결과와 같은 형식으로 출력하시오.
/*
<실행결과>
2016-12-27
*/
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
class Sol_Exercise10_7 {
public static void main(String[] args) {
Calendar c1 = Calendar.getInstance();
c1.set(2016, 11, 1); //⭐⭐ Month는 항상 -1을 붙여야 한다는 사실을 잊지말자!
while (true) {
if(c1.get(Calendar.DAY_OF_WEEK)==3) { //첫 번째 화요일
c1.add(Calendar.DAY_OF_MONTH, 21); //3주 뒤 (4번째 화요일 날짜)
String result = new SimpleDateFormat("yyyy-MM-dd").format(c1.getTimeInMillis());
System.out.println(result);
break;
}
c1.add(Calendar.DAY_OF_MONTH, 1);
}
}
}
/*
<풀이 접근>
1. 2016년 1월 1일로 Calendar객체 set.
2. DAY_OF_WEEK가 3(화)이 나오는 순간을 날짜를 하나씩 add해가며 찾는다.
3. 해당 날짜 + 21일이 3주 뒤의 네 번째 화요일이므로 add(일, 21)을 한다.
4. DateFormat으로 "2016-12-27" 패턴을 통해 format(d)한다.
*/
/*
<정답 풀이>
💡[정답] ?째주 ?요일은 TemporalAdjusters클래스의 dayOfWeekInMonth()를 이용하면 된다.
*/
import java.time.*;
import static java.time.DayOfWeek.*;
import static java.time.temporal.TemporalAdjusters.*;
class Exercise10_7 {
public static void main(String[] args) {
LocalDate date = LocalDate.of(2016, 12, 1);
System.out.println(date.with(dayOfWeekInMonth(4, TUESDAY)));
}
}
//[10-8] 서울과 뉴욕간의 시차가 얼마인지 계산하여 출력하시오.
/*
<실행결과>
2016-01-28T23:01:00.136+09:00[Asia/Seoul]
2016-01-28T09:01:00.138-05:00[America/New_York] sec1=32400
sec2=-18000
diff=14 hrs
*/
class Exercise10_8 {
public static void main(String[] args) {
ZonedDateTime zdt = ZonedDateTime.now();
ZoneId nyId = ZoneId.of("America/New_York");
ZonedDateTime zdtNY = ZonedDateTime.now().withZoneSameInstant(nyId);
System.out.println(zdt); System.out.println(zdtNY);
long sec1 = zdt.getOffset().getTotalSeconds();
long sec2 = zdtNY.getOffset().getTotalSeconds();
long diff = (sec1 - sec2)/3600;
System.out.println("sec1="+sec1);
System.out.println("sec2="+sec2);
System.out.printf("diff=%d hrs%n",diff);
}
}
<정답>
[해설]
ZonedDateTime의 getOffset()은 ZoneOffset을 반환한다.
ZoneOffset의 getTotalSeconds()를 호출하면, 날짜와 시간을
초단위로 변환한 결과를 얻을 수 있다.
ZoneOffset offset = zdt.getOffset();
long sec1 = offset.getTotalSeconds();
현재 서울과 뉴욕의 날짜와 시간을 초단위로 바꾼다음에,
차이를 구하면 시차를 초단위로 구할 수 있다.
이 값을 3600초(1시간)으로 나누면, 시간단위의 값을 구할 수 있다.