////
Search
📅

9장 새로운 날짜와 시간 API

모든 시스템에서 가장 중요한 것은 시간이다. 하지만 자바 8이전의 시간을 사용하는 API는 많은 문제를 내포하고 있었고 새로운 API가 등장했다. 이를 이용해서 우리는 시간을 만들고 조작하고 포매팅하는 과정을 배워볼 것이다.
1.
자바 8에서 새로운 날짜와 시간 라이브러리를 제공하는 이유
2.
사람이나 기계가 이해할 수 있는 날짜와 시간 표현 방법
3.
시간의 양 정의하기
4.
날짜 조작, 포매팅, 파싱
5.
시간대와 캘린더 다루기

자바 8에서 새로운 날짜와 시간 라이브러리를 제공하는 이유?

Date? Calendar?

자바 API는 복잡한 애플리케이션을 만드는 데 필요한 여러 가지 유용한 컴포넌트를 제공한다. 하지만 이러한 자바 API는 완벽하지 못하다. 특히 시간과 날짜를 지원하는 자바의 API는 정말 많은 문제가 있었다.
자바 1.0의 Date와 자바 1.1의 Calendar의 문제점?
토글로 만들 정도로 많은 문제점을 날짜와 시간 라이브러리는 가지고 있었다... 그래서 자바 개발자들은 스트레스를 견디지 못하고 Joda-Time 과 같은 서드파티 날짜와 시간 라이브러리를 사용했다. 하지만 우리의 스트레스를 알고 있던 오라클은 좀 더 훌륭한 날짜와 시간 API를 제공하기로 했다. 결국 자바 8에서는 Joda-Time 과의 많은 기능이 java.time 패키지로 추가했다.

사람이나 기계가 이해할 수 있는 날짜와 시간 표현 방법과 시간의 양 정의하기

LocalDate, LocalTime, Instant, Dration, Period 클래스

'사람이 이해할 수 있는' 또는 '기계가 이해할 수 있는' 시간 표현 방법으로 나눌 수 있다. 사람이 이해하는 날짜는 '2021-06-04' 와 같이 표현할 수 있다. 또한 기계가 이해할 수 있는 날짜는 '1256953732' 과 같은 날짜이다. 이를 만드는 방법과 변환 방법을 배워본다.
사람이 이해할 수 있는 날짜
기계가 이해할 수 있는 날짜
Duration? Period? 너흰 뭐야? (시간과 날짜의 간격을 알 수 있는 방법)
지금까지 모든 클래스는 불변이다. 불변 클래스는 함수형 프로그래밍 그리고 스레드 안전성과 도메인 모델의 일관성을 유지하는 데 좋은 특징이다. 하지만 새로운 날짜와 시간 API에서는 변경된 객체 버전을 만들 수 있는 메서드를 제공한다. 예를 들어 기존 LocalDate 인스턴스에 3일을 더해야 하는 상황이 발생할 수 있다. 이런 경우에는 어떻게 해야할까? (불변이라면 못고칠텐뎅....)

날짜 조작, 포매팅, 파싱

날짜 조작하기 (간단하게 조작)
날짜 조작하기 (조금 복잡한 계산)
날짜와 시간 객체 출력과 파싱

시간대와 캘린더 다루기

지금까지 살펴본 모든 클래스에는 시간대와 관련한 정보가 없다.(예를 들자면 우리나라의 시간대는 도쿄를 기준으로 하고 있다.) 새로운 날짜와 시간 API의 큰 편리함 중 하나는 시간대를 간단하게 처리할 수 있다는 점이다. 기존 java.time.TimeZone을 대체할 수 있는 java.time.ZoneId 클래스가 새롭게 등장했다. 새로운 클래스를 이용하면 서머타임Daylight saving Time(DST)과 같은 복잡한 사항이 자동으로 처리된다. 날짜와 시간 API애서 제공하는 다른 클래스와 마찬가지로 ZoneId는 불변 클래스다.
시간대 사용하기
날짜와 시간 API의 설계자는 ChronoLocalDate보다 LocalDate를 사용하라고 권고한다. 예를 들어 1년은 12개월로 이루어져 있으며 1달은 31일 이하이거나, 최소한 1년은 정해진 수의 달로 이루어졌을 것을 가정할 수 있다. 하지만 이와 가정은 특히 멀티캘린더 시스템에서 적용되지 않는다. 따라서 프로그램의 입출력을 지역화하는 상황을 제외하고는 모든 데이터 저장,조작,비즈니스 규칙 해석 등의 작업에서 LocalDate를 사용해야한다.
결론
자바 8이전의 java.util.Date 는 상당히 별로다. 이유는 가변객체, 오프셋 문제, 달의 인덱스문제, 잘못된 이름 등등
새로운 날짜 API의 경우 모두 불변 객체이다.
새로운 API의 경우 기계와 사람이 이해할 수 있는 두가지의 상황을 모두 제공한다. (Instant, LocalDateTime)
날짜와 시간 객체는 상대적으로도 처리할 수 있으며 절대적인 방식으로 처리하여 변경할 수 있다. 하지만 이 변경의 결과는 기존의 인스턴스를 바꾸는 것이 아닌 결과로 새로운 인스턴스를 생성한다.
TemporalAdjuster은 복잡한 동작도 수행할 수 있다.
날짜와 시간 객체를 특정 포맷으로 출력하고 파싱하는 포매터를 정의할 수 있다. 스레드 안전성을 보장한다. (자바 8 이전의 format은 스레드 세이프하지 못했다.)
특정지역/장소에 상대적인 시간대 또는 UTC/GMT 기준의 오프셋을 이용해서 시간대를 정의할 수 있다.(ZoneId)