12장
1. 기존 날짜와 시간 API 문제점
자바 1.0에서 제공된 java.util.Date 클래스는 문제가 많았다.
Date 클래스인데 밀리초 단위로 표현
1900년을 기준으로 하는 오프셋
0에서 시작하는 달 인덱스
toString으로 반환되는 문자열(추가 활용 어려움)
JVM의 기본 시간대인 CET(Central European Time) 사용
DateFormat이 스레드에 안전하지 않음
Date 클래스의 문제를 해결하기 위해 자바 1.1에서는 java.util.Calendar 클래스를 제공했다. 안타깝게도 이 클래스 역시 문제가 많았다.
0에서 시작하는 달 인덱스
DateFormat 같은 기능은 Date 클래스에서만 작동
Date와 Calendar 클래스 둘 다 가변(mutable) 클래스라 유지보수가 어려웠다. 부실한 API로 인해 Joda-Time 같은 외부 라이브러리가 유행했다. 결국 자바 8에서 Joda-Time의 많은 기능을 java.time 패키지로 추가했다.
2. java.time 패키지
2.1. LocalDate
LocalDate 인스턴스는 시간을 제외한 날짜를 표현하는 불변 객체다. LocalDate 클래스는 팩토리 메서드 of, now, get 등을 제공한다. 팩토리 메서드 of는 LocalDate 인스턴스를 생성하고, 팩토리 메서드 now는 현재 날짜 정보를 얻을 수 있고, 팩토리 메서드 get은 TemopralField를 전달해서 정보를 얻을 수 있다. ToemporalField는 시간 관련 객체에서 어떤 필드의 값에 접근할지를 정의하는 인터페이스다.
2.2. LocalTime
LocalTime 인스턴스는 시간을 표현하는 객체다.
2.3. LocalDateTime
LocalDateTime은 LocalDate와 LocalTime을 쌍으로 갖는 복합 클래스다. 따라서 날짜와 시간을 모두 표현할 수 있다.
2.4. Instant
java.time.Instant 클래스는 유닉스 에포크 시간(Unix epoch time, 1970.01.01.00:00:00 UTC)를 기준으로 특정 지점까지의 시간을 초로 표현한다. Instant에서는 Duration과 Period 클래스를 함께 활용할 수 있다. 팩토리 메서드 ofEpochSecond에 초를 넘겨줘서 Instant 클래스의 인스턴스를 만들 수 있다. Instant 클래스는 나노초(10억분의 1초)의 정밀도르 제공한다.
2.5. Duration과 Period
Duration과 Period 클래스로 두 시간 객체 사이의 지속 시간을 만들 수 있다. Duration 클래스는 초와 나노초로 시간 단위를 표현하므로 LocalDate를 넘길 수 없다. Period는 LocalDate를 인수로 받을 수 있다.
3. 날짜 조정, 파싱, 포매팅
3.1. 날짜 조정
withAttribute 메서드로 기존의 LocalDate를 바꾼 버전을 간단하게 만들 수 있다. 단, 모든 메서드는 기존 객체를 바꾸지 않고 새로운 객체를 반환한다.
좀 더 복잡하게 날짜를 조정하기 위해 TemporalAdjusters를 사용할 수 있다.
3.2. 파싱과 포매팅
java.util.DateFormat을 대체할 수 있도록 파싱과 포매팅 전용 패키지인 java.time.format이 추가되었다. 이 패키지에 정의된 DateTimeFormatter로 포매터를 만들 수 있다. DateTimeFormatter는 스레드에서 안전하게 사용할 수 있다. DateTimeFormatter는 특정 패턴으로 포매터를 만들 수 있는 정적 팩토리 메서드도 제공한다.
4. 다양한 시간대와 캘린더 활용
java.util.TimeZone을 대체할 수 있도록 시간대를 처리하는 java.time.ZoneId 클래스가 새로 등장했다. java.time.ZoneId는 서머 타임(DST)과 같은 복잡한 사항이 자동으로 처리된다. 다른 API와 마찬가지로 ZoneId는 불변 클래스다. 표준 시간대가 같은 지역을 묶어서 시간대(time zone) 규칙 집합을 정의한다. ZoneRules 클래스에는 40개 정도의 시간대가 있다. ZoneId의 getRules()를 이용해서 시간대의 규정을 획득할 수 있다. 지역 ID는 '{지역}/{도시}' 형식으로 ZoneId를 구분하는 기준이다. 기존의 TimeZone 객체는 toZoneId로 ZoneId 객체로 변환할 수 있다.ZoneId 객체는 ZoneDateTime 인스턴스로 변환할 수 있다. ZoneDateTime은 지정한 시간대의 상대적인 시점으 표현한다.

참고 자료
모던 자바 인 액션 - 한빛미디어
Last updated