Goal

  • Time API가 생긴 배경(이유)
  • 주요 API 설명

 

자바 8에서 새로운 날짜와 시간 API가 생긴 이유

  • 그전까지 사용하던 java.util.Date클래스는 mutable하기 때문에 thread safe하지 않습니다.
  • 클래스 이름이 명확하지 않다. Date인데 시간까지 다룹니다.
  • 버그 발생할 여지가 많다 (타입 안전성이 없고, 월이 0부터 시작한거나)

 

예제를 위한 코드

public static void main(String[] args) throws InterruptedException {
Date date = new Date(); // 이름은 데이트인데 시간까지 다룬다
long time = date.getTime();
System.out.println(time); // 기계 시간 출력됨
// mutable 예제
Thread.sleep(1000 * 3);
Date after3Seconds = new Date();
System.out.println("after3Seconds = " + after3Seconds); // 3초 이후 시간
after3Seconds.setTime(time);
System.out.println("after3Seconds = " + after3Seconds); // 3초 이전 시간으로 변경
// mutable객체는 멀티쓰레드 환경에서 안전하게 사용하기 어렵다.
// Thread1이 Date를 사용중에 Thread2가 끼어들어서 값을 바꿀 수도 있다.
// 버그가 발생할 수 있다.
GregorianCalendar calendar = new GregorianCalendar(2000, 7, 15);
// 숫자로 사용할 경우 조심 month 조심 0부터 시작함 실수할 여지가 많음 (type safe하지 않음)
}

 


 

주요 API

  • 기계용 시간 (machine time)과 인류용 시간(human time)으로 나눌 수 있습니다.
  • 기계용 시간은 EPOCK (1970년 1월 1일 0시 0분 0초)부터 현재까지의 타임스탬프를 표현합니다.
  • 인류용 시간은 우리가 흔히 사용하는 연,월,일,시,분,초 등을 표현합니다.
  • 타임스탬프는 Instant를 사용합니다.
  • 특정 날짜(LocalDate), 시간(LocalTime), 일시(LocalDateTime)를 사용할 수 있습니다.
  • 기간을 표현할 때는 Duration (시간 기반)과 Period (날짜 기반)를 사용할 수 있습니다.
  • DateTimeFormatter를 사용해서 일시를 특정한 문자열로 포매팅할 수 있습니다.

 

현재 시간을 기계 시간으로 표현

  • Instant.now(); 현재 UTC (GMT)를 리턴합니다.
Instant instant = Instant.now();
System.out.println("instant = " + instant); // GMT , UTC 시간
ZoneId zone = ZoneId.systemDefault(); // 시스템 기준 시점
System.out.println("zone = " + zone);
ZonedDateTime zonedDateTime = instant.atZone(zone); // 시스템 기준 시점 시간
System.out.println("zonedDateTime = " + zonedDateTime);

인류용 일시를 표현하는 방법

LocalDateTime now = LocalDateTime.now(); // 현재 시스템 Zone에 해당하는 일시를 리턴한다
LocalDateTime past =
LocalDateTime.of(1999, Month.APRIL, 15, 0, 0, 0);
// 로컬의 특정 일시
ZonedDateTime seoul = ZonedDateTime.now(ZoneId.of("Asia/Seoul")); // 특정 Zone의 특정 일시를 리턴

 

기간을 표현하는 방법

  • Period / Duration . beteen() 
LocalDate today = LocalDate.now();
LocalDate christmas = LocalDate.of(2020, Month.DECEMBER, 25);
Period between = Period.between(today, christmas); // *주의* 년 월 일로 반환합니다.
System.out.println(between.getMonths());
System.out.println(between.getDays());
System.out.println(between.get(ChronoUnit.DAYS)); // 위랑 똑같음
long betweenDays = ChronoUnit.DAYS.between(today, christmas); // 오직 일수만 계산해서 반환합니다.
System.out.println("between = " + betweenDays);

 

포매팅

LocalDateTime now = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yy");
System.out.println(now.format(formatter));

 

읽어주셔서 감사합니다.

피드백, 문의 댓글로 남겨주시면 감사하겠습니다.

 

References


www.inflearn.com/course/the-java-java8/dashboard

docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#predefined