12장 새로운 날짜와 시간 API

자바 8 인 액션 12장을 요약한 내용 입니다.

자바 1.0에서는 java.util.Datearrow-up-right 클래스 하나로 날짜와 시간 관련 기능을 제공했다. 날짜를 의미하는 Date라는 클래스의 이름과 달리 Date 클래스는 특정 시점을 날짜가 아닌 밀리초 단위로 표현한다. 게다가 1900년을 기준으로 하는 오프셋, 0에서 시작하는 달 인덱스 등 모호한 설계로 유용성이 떨어졌다. 그리고 Date는 JVM 기본시간대인 CET, 즉 중앙 유럽 시간대를 사용하였다.

자바 1.0의 Date 클래스에 문제가 있다는 의문이 있었지만 과거 버전과 호환성을 깨뜨리지 않으면서 이를 해결할 수 있는 방법이 없었다. DateFormat에도 문제가 있었다. 예를 들어 DateFormat은 스레드에 안전하지 않다. 즉, 두 스레드가 동시에 하나의 포매터로 날짜를 파싱할 때 예기치 못한 결과가 일어날 수 있었다.

DateFormat을 사용하여 스레드 세이프 하지 않은 결과란?

마지막으로 Date와 Calendar는 모두 가변 클래스다. 가변 클래스라는 설계 때문에 유지보수가 아주 어려워진다. 오라클은 좀 더 훌륭한 날짜와 시간 API를 제공하기로 결정했다. 결국 자바 8에서는 joda-Time의 많은 기능을 java.time 패키지로 추가했다.

LocalDate와 LocalTime 사용

LocalDateTime은 LocalDate와 LocalTime을 쌍으로 갖는 복합 클래스다.

LocalDate date = LocalDate.of(2014, 3, 18); // 2014-03-18
int year = date.getYear // 2014
DayOfWeek dow = date.getDayOfWeek(); // TUESDAY

LocalTime time = LocalTime.of(13, 45, 20);
int hour = time.getHour(); // 13
int minute = time.getMinute(); // 45

LocalDateTime dt1 = LocalDateTime.of(2014, Month.MARCH, 18, 13, 45, 20);
LocalDateTime dt2 = LocalDateTime.of(date, time);

Instant : 기계의 날짜와 시간

사람은 보통 주, 날짜, 시간, 분으로 날짜와 시간을 계산한다. 하지만 기계에서는 이와 같은 단위로 시간을 표현하기 어렵다. 기계의 관점에서는 연속된 시간에서 특정 지점을 하나의 큰 수로 표현하는 것이 가장 자연스러운 시간 표현 방법이다.

Duration과 Period 정의

Duration 클래스의 정적 팩토리 메서드 between으로 두 시간 객체 사이의 지속시간을 만들 수 있다.

간격을 표현하는 날짜와 시간 클래스의 공통 메서드arrow-up-right

날짜 조정, 파싱, 포매팅

withAtrribute 메서드로 기존의 LocalDate를 바꾼 버전을 직접 간단하게 만들 수 있다.

plus, minus 메서드 등을 사용해서 Temporal을 특정 시간만큼 앞뒤로 이동시킬 수 있다.

특정 시점을 표현하는 날짜 시간 클래스의 공통 메서드arrow-up-right

TemporalAdjusters 사용하기

지금까지 살펴본 날짜 조정 기능은 비교적 간단한 편에 속한다. 때로는 다음 주 일요일, 돌아오는 평일, 어떤 달의 마지막 날 등 좀 더 복잡한 날짜 조정 기능이 필요할 것이다.

TemporalAdjusters 클래스의 팩토리 메서드arrow-up-right

날짜와 시간 객체 출력과 파싱

DateTimeFormatter를 이용해서 날짜나 시간을 특정 형식의 문자열로 만들 수 있다.

또한 다음 예제에서 보여주는 것처럼 DateTimeFormatter 클래스는 특정 패턴으로 포매터를 만들 수 있는 정적 팩토리 메서드도 제공한다.

DateTimeFormatterBuilder에 이용하면 프로그램적으로 포매터를 만들 수 있다.

다양한 시간대와 캘린더 활용 방법

새로운 날짜와 시간 API의 큰 편리함 중 하나는 시간대를 간단하게 처리할 수 있다는 점이다. 새로운 클래스를 이용하면 서머타임(DST) 같은 복잡한 사항이 자동으로 처리된다.

요약

  • 자바 8 이전 버전에서 제공하는 기존의 java.util.Datearrow-up-right 클래스와 관련 클래스에서는 여러 불일치점들과 가변성, 어설픈 오프셋, 기본값, 잘못된 이름 결정 등의 설계 결함이 존재했다.

  • 새로운 날짜와 시간 API에서 날짜와 시간 객체는 모두 불변이다.

  • 새로운 API는 각각 사람과 기계가 편리하게 날짜와 시간 정보를 관리할 수 있도록 두 가지 표현 방식을 제공한다.

  • 날짜와 시간 객체를 절대적인 방법과 상대적인 방법으로 처리할 수 있으며 기존 인스턴스를 변환하지 않도록 처리 결과로 새로운 인스턴스가 생성된다.

  • TemporalAdjuster를 이용하면 단순히 값을 바꾸는 것 이상의 복잡한 동작을 수행할 수 있으며 자신만의 커스텀 날짜 변환 기능을 정의할 수 있다.

  • 날짜와 시간 객체를 특정 포맷으로 출력하고 파싱하는 포매터를 정의할 수 있다. 패턴을 이용하거나 프로그램으로 포매터를 만들 수 있으며 포매터는 스레드 안전성을 보장한다.

  • 특정 지역/장소에 상대적인 시간대 또는 UTC/GMT 기준의 오프셋을 이용해서 시간대를 정의할 수 있으며 이 시간대를 날짜와 시간 객체에 적용해서 지역화할 수 있다.

  • ISO-8601 표준 시스템을 준수하지 않는 캘린더 시스템도 사용할 수 있다.

Last updated