java.util.Date vs java.time.LocalDate
자바에서 날짜를 지원하는 대표적인 API 는 2가지가 있다.
java.util.Date: Java 8 이전부터 존재한 API 이다.java.time.LocalDate: Java 8 부터 생긴 API 이다.
java.util.Date 는 이름과 다르게 날짜 뿐 아니라 시간까지 다룬다. 반면, java.time.LocalDate 는 날짜만 다루는 역할을 하고, 시간까지 다루기 위한 java.time.LocalDateTime 이라는 API 가 따로 정의되어 있다.
위의 두개 객체 중에서 java.time 패키지에 있는 LocalDate 를 사용하는 것이 권장된다.
예전엔 날짜를 다루기 위해서
java.util.Date,java.util.Calendar,java.util.Timezone이라는 노답 삼형제 같은 API 들이 존재했다. 과거의 유산으로 남겨두고 새로운 프로젝트에 다시는 쓰지 말자. 옛날 프로젝트에 보인다면, 시간이 있을 때 열심히 리팩토링해주자.
java.time.LocalDate 는 무엇이 좋은가?
왜 써야하는지를 알아야 장점을 십분 활용할 수 있을 것이다. 그리고 나중에 API 를 직접 만들 때도 아래와 같은 사항들을 고려하여 설계할 수 있을 것이다.
API 가 명확해졌다.
API 가 명확해졌다는 것은 이해하기 쉬워졌다는 것이다. 기존 Date 클래스의 경우, Date 라는 이름과 달리 시간까지 포함하고 있었다. 또한 Calendar 클래스의 경우, 월은 0-11 까지의 숫자로 표현하면서 일은 1-31 까지의 숫자로 표현하는 등 일관성이 없고 해당 클래스에 대한 지식이 어렵다면 이해하기가 쉽지 않았다.
java.time.LocalDate 는 위와 같이 사람을 헷갈리게 하지 않는다.
유용한 유틸 메서드를 제공한다.
java.time.LocalDate 는 나중에 나온만큼 날짜에 관련된 로직을 만들 때 자주 사용되는 여러가지 기능을 추가했다.
- 포맷, 파싱이 더 쉬워졌다. API에서 자체적으로 포맷, 파싱 메서드를 제공한다.
- 날짜 더하기, 빼기 기능을 지원한다. API 에서 자체적으로 더하기, 빼기 메서드를 제공한다.
API 가 유연하다.
Date 클래스는 유닉스 시간으로 표현된 Timestamp 의 역할만 가능했다. Unix epoch 로 부터 얼마만큼의 milliseconds 가 흘러갔는지만 표현이 가능했다. Date 라고 하지만, 날짜가 아닌 특정 시점(Timestamp)만 표현이 가능했다는 것이다.
새롭게 등장한 java.time API 에는 다양한 클래스가 존재한다.
Instant: Timestamp 와 같이 특정 시점을 표현한다.LocalDate: 연, 월, 일로 구성된 날짜를 표현한다.LocalDateTime:LocalDate에 nano seconds 정확도로 표현된 시간을 더해 표현한다.OffsetDateTime:LocalDateTime과 같은데, time zone offset 을 더해 표현한다.ZonedDateTime:OffsetDateTime과 같은데, time zone ID 를 포함하여 표현한다.MonthDay: 연도나 시간 없이 월 일로만 표현한다.YearMonth: 연도와 월로만 표현한다.Duration: 초, 분, 시로 표현되는 기간이다.Period: 일, 월, 년으로 표현되는 기간이다.
불변성을 보장하며, 스레드 안전(thread-safe)하다.
모든 변화를 주는 (Mutating) 메서드는 기존 오브젝트에서 상태를 변화시키는 것이 아니라, 새로운 오브젝트를 반환한다.
java.util.Date는 불변성 보장이 되어있지 않아 동시성 프로그램에서 미묘한 버그를 만들어내는 일이 종종 있었다.
간단한 API 이용법
테스트 코드를 통해 간단한 LocalDate 의 활용법을 알아보자.
날짜를 yyyy-MM-dd 형태로 출력하기
@Test
@DisplayName("LocalDateTime 오브젝트의 표현을 yyyy-mm-dd 로 바꾸어봅니다.")
void changeToYyyyMmDd() {
LocalDate localDate = LocalDate.of(2022, 4, 15);
String localDateYyyyMmDd = localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
assertThat(localDateYyyyMmDd).isEqualTo("2022-04-15");
}
서로 다른 날짜를 비교해보기
@Test
@DisplayName("날짜 비교 테스트")
void compareLocalDate() {
LocalDate localDate20220414 = LocalDate.of(2022, 4, 14);
LocalDate localDate20220415 = LocalDate.of(2022, 4, 15);
LocalDate localDate20220416 = LocalDate.of(2022, 4, 16);
assertThat(localDate20220415.isAfter(localDate20220414)).isTrue();
assertThat(localDate20220414.isBefore(localDate20220415)).isTrue();
assertThat(localDate20220416.isBefore(localDate20220415)).isFalse();
}
레퍼런스
Should I use java.util.Date or switch to java.time.LocalDate
Migrating to the New Java 8 Date Time API
'Java > 자바 잡지식' 카테고리의 다른 글
| 로컬과 운영 환경의 log4j 나누기 (0) | 2022.12.28 |
|---|---|
| ObjectMapper (Jackson) 커스텀 직렬화 역직렬화 구현 (0) | 2022.05.23 |
| javadoc 한글 깨짐 문제 해결 (0) | 2022.05.15 |
| Filter, Interceptor, AOP 알아보기 (0) | 2022.05.10 |
| 스프링의 Interceptor 란 무엇일까? [공식문서 번역] (0) | 2022.05.04 |