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