Intro
제법 오래된 프로젝트를 유지보수 하고 개선하다보니, Date 타입을 다루어야 할 일이 제법 많이 있습니다.
Date API는 JDK 1.0 부터 제공된 유구한 역사를 가진 클래스인데요, 워낙 문제가 많다보니 JDK 1.1에서 바로 Calendar 클래스가 추가 되며 Date의 많은 메서드들을 @Deprecated
시켜버렸지만 여전히 오랜기간 꾸준히 애용되어 왔습니다.
그러다 마침내 JDK 1.8 버전에서 JodaTime 의 날짜와 시간 API가 추가되면서 LocalDateTime 이나 LocalDate를 사용 할 수 있게 되었습니다.
기존에 있는 Date를 걷어낼 수 있으면 참 좋겠지만, 그럴 여유가 없을 경우에는 일단 새로 작성하는 코드들에서 최대한 Date 사용을 피하지만, 어쩔 수 없이 부딪치는 경우에는 서로간의 변환이 필요합니다.
지금까지 서로간 변환하는 일은 종종 있었는데, 스스로 레퍼런스를 작성 해 두어서 필요할 때 좀 더 쉽게 찾아 쓰려고 합니다. 프로젝트에 있는 유틸 클래스에 해당 기능을 저장 해 둔다면 좀 더 편하게 사용 할 수 있습니다.
Date -> LocalDateTime
첫번째로, Date 객체를 LocalDateTime으로 변환하는 것을 알아보겠습니다.
LocalDateTime이나 LocalDate 둘 다 변환하는 과정은 비슷 하니, 가장 많이 쓰이는 LocalDateTime으로 해보겠습니다.
Date now = new Date();
LocalDateTime localDateTime = now.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
Date -> Instant -> ZonedDateTime -> LocalDateTime 순서로 변환되며 최종적으로 LocalDateTime 객체를 얻습니다.
특정 ZoneId를 사용해야 한다면, ZoneId.systemDefault()
대신 작성 하면 됩니다.
아래는 제대로 변환이 되는지 확인을 위해 작성 해둔 테스트 코드 입니다.
@Test
@DisplayName("Date -> LocalDateTime")
public void DateToLocalDateTime() {
Date now = new Date();
LocalDateTime localDateTime = now.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
Calendar cal = Calendar.getInstance();
cal.setTime(now);
// year
assertThat(cal.get(Calendar.YEAR)).isEqualTo(localDateTime.getYear());
// month
assertThat(cal.get(Calendar.MONTH) + 1).isEqualTo(localDateTime.getMonth().getValue());
// date
assertThat(cal.get(Calendar.DATE)).isEqualTo(localDateTime.getDayOfMonth());
// ms
assertThat(now.getTime()).isEqualTo(localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
}
LocalDateTime -> Date
이번에는 반대의 경우입니다.
LocalDateTime now = LocalDateTime.now();
Date date = Date.from(now.atZone(ZoneId.systemDefault()).toInstant());
LocalDateTime -> ZonedDateTime -> Instant -> Date로, 위에서와 정확히 반대의 과정을 거쳐 변환됩니다.
테스트 코드는 아래와 같이 작성 해 보았습니다.
@Test
@DisplayName("LocalDateTime -> Date")
public void LocalDateTimeToDate() {
LocalDateTime now = LocalDateTime.now();
Date date = Date.from(now.atZone(ZoneId.systemDefault()).toInstant());
Calendar cal = Calendar.getInstance();
cal.setTime(date);
// year
assertThat(cal.get(Calendar.YEAR)).isEqualTo(now.getYear());
// month
assertThat(cal.get(Calendar.MONTH) + 1).isEqualTo(now.getMonth().getValue());
// date
assertThat(cal.get(Calendar.DATE)).isEqualTo(now.getDayOfMonth());
// ms
assertThat(date.getTime()).isEqualTo(now.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
}
모든 테스트 케이스를 정상적으로 통과하여, 동작에 문제 없음을 확인 하였습니다.
이상입니다.
ref: https://www.baeldung.com/java-date-to-localdate-and-localdatetime
'Programming > Java' 카테고리의 다른 글
[JAVA] zxing 활용해 QR코드 생성하기 (0) | 2022.06.30 |
---|---|
JAVA) 자바에서는 Call By Reference가 불가능 합니다. (0) | 2022.06.06 |
Java) HashMap에서 특정 value를 제거하기 (0) | 2022.05.13 |
JAVA) Private method를 테스트 하는법 (0) | 2022.05.09 |
Java) new int[Integer.MAX_VALUE] (0) | 2022.04.29 |