Java/Java의 정석

Chapter 10 날짜와 시간 & 형식화 date, time and formatting

계란💕 2022. 2. 28. 10:24

1.날짜와 시간

  1.1 Calendar 와 Date

  - Date -> Calendar(오래 쓰다가 바뀜) -> time

  - 실무에서는 아직 Calendar을 쓰기도 한다.

  - Calendar 클래스

    -> 추상 클래스(인스턴스 생성 불가)이므로 getInstance() - (static)를 통해 구현된 객체를 얻어야 한다.

  - Calendar 클래스

  - Date와 Calendar 간의 변환

    -> Date의 메서드는 대부분 'deprecated-더 이상 사용을 권장하지 않음.'되었지만 여전히 사용한다. "하위 호환성"

 

  - 컴퓨터는 항상 시간정수로 저장한다. 

  - clear(int field)는 Calendar 객체의 모든(특정) 필드를 초기화한다.

     -> 1970년 1월 1일 00:00:00 (EPOCH TIME)

  

  - add(): 특정 필드의 값을 증가 또는 감소 (다른 필드에 영향 O)

  - roll(): 특정 필드의 값을 증가 또는 감소 (다른 필드에 영향 X)

 

  Ex) Date와 Calendar 간의 변환

<hide/>
package first;
import java.util.*;
public class CalendarEx1 {
	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));
		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: 일요일, ... 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));
		
		System.out.println("TimeZone(-12~+12) : " + (today.get(Calendar.ZONE_OFFSET)/(60 * 60 * 1000)  ));
		System.out.println("이 달의 마지막 날 : " + today.getActualMaximum(Calendar.DATE)  ); 	// 이 달의 마지막 날을 찾는다.
		
	}	
}

  Note) 실행 결과

  - getInstance() : 현재 날짜와 시간

  - set()메서드를 이용하면 원하는 날짜와 시간 정할 수 있다. 

  - get(Calendar.MONTH) : 0~11 => 1~12월을 의미한다.

 

  Ex) 두 날짜의 차이 구하기

<hide/>
package javaStudy;
import java.util.*;
public class CalendarEx2 {
	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)] + "요일입니다. " );
			
		// 두 날짜간의 차이를 얻으려면, getTimeInMills(): 천분의 일초 단위로 변환해야한다.
		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) + "월 " + date.get(Calendar.DATE) + "일 ";		
	}
}

  Note) 실행 결과

  - 두 날짜를 최소 단위인 초 단위로 바꾸고 그 차이를 구한다.

  - getTimeInMillis() : 1/1000초 단위로 값을 반환하기 때문에 

    -> '초' 단위로 얻으려면 1000으로 나눈다.

    -> '일' 단위로 얻으려면: 24 * 60 * 60 * 1000으로 나눈다.

 

  - add(int field, int amount) : 지정한 필드의 값을 원하는 만큼 증가/감소 시킬 수 있다.

  - roll(int field, int amount) : 지정한 필드의 값을 원하는 만큼 증가/감소 시킬 수 있다.(다른 필드의 값에 영향 X)

    -> 날짜 필드의 값을 31일 증가시키면 add는 월, 일이 함께 변하지만, roll은 일 필드의 값만 변한다.

 

  Ex)

<hide/>
import java.util.Calendar;
public class CalendarEx {
	public static void main(String[] args) {
		
		if(args.length != 2) {
			System.out.println("Usage: java Calendar Ex6 2015 9" );
			return;
		}
		int year = Integer.parseInt(args[0]);
		int month = Integer.parseInt(args[1]);
		int START_DAY_OF_WEEK = 0;
		int END_DAY = 0;
		
		Calendar sDay = Calendar.getInstance();  //시작일
		Calendar eDay = Calendar.getInstance(); // 끝일
		
		// 월의 경우 0부터 11까지 값을 가지므로 1을 빼준다.
		// 예를 들어, 2015년 11월 1일은 sDay.set(2015, 10, 1);과 같이 해줘야 한다.
		sDay.set(year, month - 1, 1);
		eDay.set(year, month, 1);
		
		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();
		}
	}
}

  Note) 실행 결과

  - 다음 달의 1일에서 하루를 빼면 이번 달의 마지막 일을 알 수 있다.

 

 

2. 형식화 클래스

  - java.text 패키지의 DecimalFormat, simpleDateFormat

  - 숫자와 날짜를 원하는 형식으로 쉽게 출력 가능(숫자, 날짜 -> 형식 문자열)

  - 형식 문자열에서 숫자와 날짜를 뽑아내는 기능(형식 문자열 -> 숫자, 날짜)

  - DecimalFormat: 숫자를 형식화할 때

  - Number 클래스: 숫자를 저장하는 래퍼 클래스의 조상

    -> Integer.parseInt()는 콤마가 포함된 문자열을 숫자로 변환하지 못한다.

 

  2.1 DecimalFormat

  - 숫자를 형식화 하는데 사용한다.

 

  2.2 SimpleDateFormat

  - 날짜와 시간을 다양한 형식으로 출력할 수 있게 해준다.

  - Date와 CalendarFormat만으로는 날짜 데이터를 원하는 형태로 다양하게 출력하기 복잡하다.

  Ex)

<hide/>
package javaStudy;
import java.util.*;
import java.text.*;
public class DateFormatEx1 {
	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));
	}
}

  Note) 실행결과

  - '(홑따옴표)는 escape기호이기 때문에 패턴 내에서 사용하기 위해서는 연속해서 두 번 사용한다. => ''

  - w(오늘은 올해의 몇 번째 주), W(오늘은 이 달의 몇 번째 주)

  - D(오늘은 올해의 D번째 날), d(오늘은 올해의 d번째 달)

  - F번째 E요일: (오늘은 이달의 F번째 E요일)

 

  Ex) 

  - Date인스턴스만 format메서드에 사용될 수 있으므로 Calendar인스턴스를 Date인스턴스로 변환해서 사용한다.

  - Date인스턴스를 Calendar로 변환할 때는 Calendar클래스의 setTimes()를 사용한다.

 

  Ex)

<hide/>
package first;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Scanner;

public class DateFormatEx4 {
	public static void main(String[] args) {
		
		String pattern = "yyyy/MM/dd";
		DateFormat df = new SimpleDateFormat(pattern);
		Scanner s = new Scanner(System.in);
		Date inDate = null;
		System.out.println("날짜를 " + pattern + "의 형태로 입력하시오. (입력예: 2015/12/31)"); 
		
		while(s.hasNextLine()) {
			
			try {
				inDate = df.parse(s.nextLine());
				break;
				
			}catch(Exception e) {
				System.out.println("날짜를 "+ pattern + "의 형태로 다시 입력하시오. (입력예: 2015/12/31)");
			}
		}

		Calendar cal = Calendar.getInstance();
		cal.setTime(inDate);
		Calendar today = Calendar.getInstance();
		long day = ( cal.getTimeInMillis() - today.getTimeInMillis() ) / (60 * 60 * 1000);
		System.out.println("입력하신 날짜는 현재와 " +day + "시간 차이가 있습니다.");
	}
}

  Note) 실행결과

 

                             

  2.3 ChoiceFormat

  - 특정 범위에 속하는 값을 문자열로 변환한다.

  - 연속적/불연속적인 값을 처리하는데 있어서 if/ switch문은 적절하지 않다.

 

  Ex)

<hide/>
package javaStudy;
import java.text.ChoiceFormat;
public class ChiceFormatEx1 {
	public static void main(String[] args) {
		double [] limits = {60, 70, 80, 90};	//오름차순으로 적는다.
		String [] grades = {"D", "C", "B", "A"};
		int [] scores = {100, 95, 88, 70, 52, 60, 70};
		ChoiceFormat form = new ChoiceFormat(limits, grades); 
		for(int i = 0; i < scores.length; ++i) {
			System.out.println(scores[i] + ":" + form.format(scores[i]) );
		}
	}
}

  Note) 실행 결과

  - limits: 경계값, 경계값은 double형으로 반드시 오름차순으로 정렬 

  - grades는 치환할 문자열을 저장한다. 

  - limits와 grades는 개수가 같아야 예외가 발생하지 않는다.

  - ChoiceFormat 다른 형태: "limit#value"

    -> '#'은 경계값을 범위에 포함, '<'는 범위에 포함하지 않는다.

 

  2.4 MessageFormat

  •   MessageFormat는 데이터를 정해진 양식에 맞게 출력할 수 있도록 한다.
  •   SimpleDateFormat 의 parse처럼  MessageFormat의 parse를 이용하면 지정된 양식에서 필요한 데이터만 추출 가능.

 

  Ex) 

</hide>
String msg = "Name: {0} \nTel: {1} \nAge: {2} \nBirthday: {3}";
Object[] arguments = {"계란", "010-0000-2222", "20", "2003-01-01"};
String result = MessageFormat.format(msg, arguments);
System.out.println(result);
System.out.println(msg);

 

  Note) 실행 결과

  • 0~3  과 같이 arguments  배열 안에 인덱스 범위가 아닌 숫자를 입력할 경우, 중괄호와 숫자가 그대로 출력된다. 

 

3. java.time패키지

  3.1 java.time패키지의 핵심클래스

  - Calendar 클래스는 날짜와 시간을 하나로 표현 <-> time클래스는 별도의 클래스로 분리한다.

    -> 시간(LocalTime) ,날짜(LocalDate), 시간 & 날짜(LocalDateTime)

  - Calendar는 ZonedDateTime처럼 날짜, 시간, 시간대까지 모두 가지고 있다.

 

  - Period와 Duration

    -> Period: 두 날짜간의 차이

    -> Duration: 시간의 차이 

 

  - now(): 현재 날짜와 시간을 저장하는 객체 생성 

  - of(): 해당 필드의 값을 순서대로 지정해주면 된다. 

 

  3.2 LocalDate() 와 LocalTime()

  - time패키지의 가장 기본이다.

  - now(), of() 모두 static 메서드

  - 특정 필드의 값 가져오기 - get() , getXXX()

  - 날짜와 시간에서 필드의 값 변경하기 - with(), plus(), minus()

    -> with() : 원하는 필드를 직접 지정 가능

  - 날짜와 시간의 비교 - isAfter(), isBefore(), isEqual()

    -> date1.compareTo(date2) : 같으면 0, date1이 이전이면 -1, date1이 이후이면 1

 

  Ex) chronrlogy(연표)

<hide/>
package javaStudy;
import java.time.*;
import java.time.temporal.*;
public class NewTimeEx1 {
	public static void main(String[] args) {
		LocalDate today = LocalDate.now();	// 오늘의 시간
		LocalTime now = LocalTime.now();	// 현재 시간
		LocalDate birthDate = LocalDate.of(1999, 12, 31);	//1999년 12월 31일
		LocalTime birthTime = LocalTime.of(23, 59, 59);		// 23시 59분 59초
		
		System.out.println("today = " + today);
		System.out.println("now = " + now);
		System.out.println("birthDate = " + birthDate); 	//1999-12-31
		System.out.println("birthTime = " + birthTime);		//23:59:59
		System.out.println(birthDate.withYear(2000));		//2000-12-31
		System.out.println(birthDate.plusDays(1));			//2000-01-01
		System.out.println(birthDate.plus(1, ChronoUnit.DAYS));		 // 2000-01-01
		System.out.println(birthTime.truncatedTo(ChronoUnit.HOURS)); // 23:59:59 -> 23:00
		System.out.println(ChronoField.CLOCK_HOUR_OF_DAY.range());	// 1 -24
		System.out.println(ChronoField.HOUR_OF_DAY.range());	 	// 0 - 23
	}
}

  Note) 실행결과

 

  3.3 Instant

  - instant는 에포크 타임(1970-01-01-00:00:00 UTC) 부터 경과된 시간을 나노초 단위로 표현한다. 

  - Instant를 생성할 때는 now() 와 ofEpochSecond()를 사용한다.

  

  3.4 LocalDateTime과 ZonedDateTime

  - ZoneOffset

    -> UTC로부터 얼마만큼 떨어져있는지를 표현한다.

    -> 서울은 +9이다. UTC보다 (32400초 = 60 * 60 * 9 ) 9시간이 빠르다.

 

  Ex)

<hide/>
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class NewTimeEx2 {

	public static void main(String[] args) {
		
		LocalDate date = LocalDate.of(2015, 12, 31);	// 2015년 12월 31일
		LocalTime time = LocalTime.of(12, 34, 56);	// 2015년 12월 31일
		
		//2015년 12월 31일 12시 34분 56초
		LocalDateTime dt = LocalDateTime.of(date, time);
		
		ZoneId zid = ZoneId.of("Asia/Seoul");
		ZonedDateTime zdt = dt.atZone(zid);
//		String strZid = zdt.getZone().getId();
		
		ZonedDateTime seoulTime = ZonedDateTime.now();
		ZoneId nyId = ZoneId.of("America/New_York");
		ZonedDateTime nyTime = ZonedDateTime.now().withZoneSameInstant(nyId);

		//ZonwsDatetime -> OffsetDateTime
		OffsetDateTime odt = zdt.toOffsetDateTime();
				
		System.out.println(dt);		
		System.out.println(zid);		
		System.out.println(zdt);		
		System.out.println(seoulTime);		
		System.out.println(nyTime);		
		System.out.println(odt);		

	}
}

  Note) 실행결과

 

  3.5 Temporaladjusters 클래스

  - 자주 쓰일만한 날짜 계산들을 대신 해주는 메서드 정의되어있다.

  Ex)

<hide/>
package javaStudy;
import java.time.*;
import java.time.temporal.*;
import static java.time.DayOfWeek.*;
import static java.time.temporal.TemporalAdjusters.*;
class DayAfterTomorrow implements TemporalAdjuster{
	@Override
	public Temporal adjustInto(Temporal temporal ) {
		return temporal.plus(2, ChronoUnit.DAYS);	
	}
}
public class NewTimeEx3 {
	public static void main(String[] args) {
		LocalDate today = LocalDate.now();
		LocalDate date = today.with(new DayAfterTomorrow());
		p(today);
		p(date);
		p(today.with(firstDayOfNextMonth()));
		p(today.with(firstDayOfMonth()));
		p(today.with(lastDayOfMonth()));
		p(today.with(firstInMonth(TUESDAY)));
		p(today.with(lastInMonth(TUESDAY)));
		p(today.with(previous(TUESDAY)));
		p(today.with(previousOrSame(TUESDAY)));
		p(today.with(next(TUESDAY)));
		p(today.with(nextOrSame(TUESDAY)));
		p(today.with(dayOfWeekInMonth(4, TUESDAY)));		
	}
	static void p(Object obj) {
		System.out.println(obj);
	}
}

  Note) 실행결과

  - adjustInto()는 내부적으로만 사용할 의도로 작성되었다. ->( with 사용)

 

  3.6 Period와 Duration

  - between() : 두 날짜의 차이를 타나타내는 Period를 얻을 수 있다. (static 메서드) 

  - until(): between()과 거의 같으나 인스턴스 메서드

  - 시간 차이를 이요할 때는 "Duration"

  - 특정 필드의 값을 얻을 때는 get()을 이용한다.

  - of(), with()

  - normalized() : 월의 값이 12을 넘지 않게, 1년 13개월 -> 2년 1개월로 바꿔 준다. (일의 길이는 그대로)

 

  Ex)

<hide/>
package javaStudy;
import java.time.*;
import java.time.temporal.*;
public class NewTimeEx4 {
	public static void main(String[] args) {
		
		LocalDate date1 = LocalDate.of(2014, 1, 1);
		LocalDate date2 = LocalDate.of(2015, 12, 31);
		Period pe = Period.between(date1, date2);
	
		System.out.println("date1 = "+ date1 );
		System.out.println("date2 = "+ date2 );
		System.out.println("pe = "+ pe );
		System.out.println("YEAR = "+ pe.get(ChronoUnit.YEARS));
		System.out.println("MONTH = "+ pe.get(ChronoUnit.MONTHS));
		System.out.println("DAY = "+ pe.get(ChronoUnit.DAYS));
		
		LocalTime time1 = LocalTime.of(0, 0, 0);
		LocalTime time2 = LocalTime.of(12, 34, 56);	// 12시간 23분 56초
		Duration du = Duration.between(time1, time2);
		System.out.println("time1 = "+ time1);
		System.out.println("time2 = "+ time2);
		System.out.println("du = "+ du);
		
		LocalTime tmpTime = LocalTime.of(0, 0).plusSeconds(du.getSeconds());
		System.out.println("HOUR = " + tmpTime.getHour());
		System.out.println("MINUTE = " + tmpTime.getMinute());
		System.out.println("SECOND = " + tmpTime.getSecond());
		System.out.println("NANO = " + tmpTime.getNano());	
	}
}

  Note) 실행결과

 

  3.7 파싱(parsing)과 포맷

  - 파싱: 날짜와 시간을 원하는 형식으로 출력하고 해석

  - 로케일에 종속된 포맷터를 생성: ofLocalizedDate(), ofLocalizedTime(), odLocalized DateTime()

  Ex)

<hide/>
package javaStudy;
import java.time.*;
import java.time.format.*;

public class DateFormatterEx1 {
	public static void main(String[] args) {
		ZonedDateTime zdateTime = ZonedDateTime.now();
		
		String [] patternArr = {
								"yyyy-MM-dd HH:mm:ss",
								"''yy년 MMM dd일 E요일",
								"yyyy-MM-dd HH:mm:ss.SSS Z VV",
								"yyyy-MM-dd hh:mm:ss a",
								"오늘은 올해의 D번째 날입니다.",
								"오늘은 이달의 d번째 날입니다.",
								"오늘은 올해의 w번째 주입니다.",
								"오늘은 이달의 W번째 주입니다.",
								"오늘은 이달의 W번째 E요일입니다.",
								};
		for(String p : patternArr) {
			DateTimeFormatter formatter = DateTimeFormatter.ofPattern(p);
			System.out.println(zdateTime.format(formatter));	
		}
	}
}

  Note) 실행결과

  - MMM: 2월

  - SSS: 천분의 일초

  - Z: zone-offset , +0900

  - VV: 시간대(ID) , Asia/Seoul

 

  - 문자열을 날짜와 시간으로 파싱하기

    -> parse()는 오버로딩된 메서드가 여러 개 있다.

    ->  다음의 두 가지가 자주 쓰인다.

static LocalDateTime parse(CharSequence text)
static LocalDateTime parse(CharSequence text, DateTimeFormatter formatter)

  - 자주 사용되는 기본적인 문자열은 형식화 상수를 사용하지 않고도 파싱이 가능하다.

  Ex)

<hide/>
package javaStudy;
import java.time.*;
import java.time.format.*;

public class DateFormatterEx2 {
	public static void main(String[] args) {
		LocalDate newYear = LocalDate.parse("2016-01-01", DateTimeFormatter.ISO_LOCAL_DATE);
		
		LocalDate date = LocalDate.parse("2001-01-01");
		LocalTime time = LocalTime.parse("23:59:59");
		LocalDateTime dateTime = LocalDateTime.parse("2001-01-01T23:59:59");
		DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		LocalDateTime endOfYear = LocalDateTime.parse("2015-12-31 23:59:59", pattern);
		
		System.out.println(newYear);
		System.out.println(date);
		System.out.println(time);
		System.out.println(dateTime);
		System.out.println(endOfYear);	
	}
}

  Note) 실행 결과

  - ofPattern()을 이용해서 파싱한다.