Java

[Java] Java 8의 특징(5) - Date와 Time

재담 2022. 2. 26. 19:17

자바 8에서 새로운 날짜와 시간 API의 등장 배경

기존에 사용하던 java.util.Date 클래스는 mutable 하기 때문에 thread safe하지 않다. 그리고 클래스 이름이 명확하지 않다. Date 클래스인데 시간까지 다룬다. 또한 버그가 발생할 여지가 많다. 타입 안정성이 없고 월이 0부터 시작한다는 문제가 있었다.

 

자바 8에서 새롭게 등장한 날짜와 시간 API에는 다음과 같은 특징이 있다.

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

 

 

Date와 Time API

현재 시간을 기계 시간으로 표현하는 방법

  • Instant.now() : 현재 UTC를 리턴
Instant now = Instant.now();
System.out.println(now);
System.out.println(now.atZone(ZoneId.of("UTC")));

ZonedDateTime zonedDateTime = now.atZone(ZoneId.systemDefault());
System.out.println(zonedDateTime);

 

인간 시간을 표현하는 방법

  • LocalDateTime.now() : 현재 시스템 Zone에 해당하는 일시를 리턴
  • LocalDateTime.of(int, Month, int, int, int, int) : 로컬의 특정 일시를 리턴
  • ZonedDateTime.of(int, Month, int, int, int, int, ZoneId) : 특정 Zone의 특정 일시를 리턴

 

기간을 표현하는 방법

  • Period.between() / Duration.between()
Period period = Period.between(LocalDate.MIN, LocalDate.MAX);
System.out.println(period.get(ChronoUnit.DAYS));

Duration duration = Duration.between(LocalTime.MIN, LocalTime.MAX);
System.out.println(duration.getSeconds());

 

포맷팅 하는 방법

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/d/yyyy");
        
LocalDate date = LocalDate.parse("07/15/1982", formatter);
System.out.println(date);

LocalDate today = LocalDate.now();
System.out.println(today.format(formatter));

 

레거시 API 지원

  • GregorianCalendar와 Date 타입의 인스턴스를 Instant나 ZonedDateTime으로 변환 가능
  • java.util.TimeZone에서 java.time.ZoneId로 상호 변환 가능
ZoneId newZoneAPI = TimeZone.getTimeZone("Asia/Seoul").toZoneId();
TimeZone legacyZoneAPI = TimeZone.getTimeZone(newZoneAPI);
System.out.println(legacyZoneAPI);

Instant newInstant = new Date().toInstant();
Date legacyInstant = Date.from(newInstant);
System.out.println(legacyInstant);

Reference