[Java] Instant & LocalDateTime 차이 알아보기.

728x90

안녕하세요 🤚

오늘은 Instant & LocalDateTime 차이에 대하여 알아보려고 합니다.

위 내용을 다루기 전에 간단하게 자바8 전 후 에 다루던 날짜, 시간 API 가 어떻게 변했는지도 살짝 알아보려고 합니다. 

 

서론

포스팅 계기

 

회사 프로젝트를 살펴보던 중 시간 관련 데이터들을 DB에 TimeStamp 로 데이터 타입이 지정되어 있었다.

그리고 엔티티에서는 LocalDateTIme 이 아닌 Instant 로 설계가 되어 있었다.

 

기존에 내가 했던 프로젝트는 DB에서 LocalDateTime 을 사용했고, 엔티티에는 DateTIme&TimeStamp 으로 설계를 해왔기 때문에

왜 그럴까? 라는 궁금증이 생겨 따로 정리를 해보고 포스팅하게 되었습니다.

 

위 내용을 설명하기 전에 간단하게 자바8 전 후 날짜,시간 API 변화에 대하여 이야기를 해보겠습니다. 

 

자바 8이전은 어땠을까?

 

기존 자바1.0 에서는 java.util.Date 클래스 하나로 날짜와 시간 관련 기능을 제공했습니다.

Date date = new Date(117,8,21);

 

출력결과

 Thu Sep 21 00:00:00 CET 2017

 

결과를 보면 아시겠지만 뭔가 직관적이지 않습니다.

 

또한 Date 클래스의 value 를 toString 으로 반환되는 문자열을 추가로 활용하기가 어렵습니다.

 

그리고 Date 는 JVM 기본 시간대인 CET, 중앙 유럽 시간대를 사용한다. 그리고 Date 클래스는 자체적으로 시간대 정보를 알고있는 것도 아닙니다.

그리고 Date 를 개선하여 Calendar 클래스가 제공되었지만, 이 또한 에러를 일으키는 설계 문제를 갖고 있습니다. 

그래서 개발자들은 Date, Calendar 어떤 클래스를 사용해야 할지 혼동을 가져왔습니다 

 

게다가 DateFormat 같은 일부 기능은 Date 클래스에만 작동하였고, DateFormat 에는 스레드에 안전하지 않습니다

즉 멀티 스레드가 동시에 하나의 포매터 날짜를 파싱할때 예기지 못한 날짜가 나타나게 될 것입니다.

 

마지막으로 Date 와 Calendar 는 모두 가변 클래스 이다. <br> 즉 유지보수가 힘들 수 있다. 위 단점들 때문에

오라클에서 Java 8 을 출시할 때 java.time 패키지가 추가 되었다.

 

자바8은 혁명적인 업데이트였고 Stream, Lambda, time 을 포함한 여러가지 기능을 추가했다. 

자바의 역사는 사실상 자바8 이전과 이후로 나뉘지 않나? 라는 개인적인 견해를 가지고 있습니다. 

 

본론

LocalDate

LocalDate date = LocalDate.of(2024,5,16); // 2024-05-16
int year = date.getYear(); // 2024
Month month = date.getMonth(); // MAY
int day = date.getDayOfMonth(); // 16
LocalDate today = LocalDate.now(); // 2024-05-16

 

LocalDate 는 시간을 포함하지 않고, 날짜에 대한 정보만 포함을 한다

 

LocalTime

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

 

위 처럼, 날짜와 시간을 따로 따로 객체를 매번 생성해서 핸들링하기는 귀찮다.

그래서 나온게 바로 LocalDateTime 이다

 

LocalDateTime

LocalDateTime 은 LocalDate + LocalTime 을 역할을 할 수 있는 복합 클래스 이다.

즉 날짜, 시간 모두 표현할 수 있다는 뜻이다.

LocalDateTime dt1 = LocalDateTime.of(2024, Month.MAY, 16, 13,45,20);

날짜와 시간을 한꺼번에 다룰 수 있고, 위 객체를 LocalDate, LocalTime 인스턴스로 추출하게 할 수도 있다.

LocalDate date1 = dt1.toLocalDate();
LocalTime time1 = dt1.toLocalTime();

 

 

다음으로는 기계의 날짜와 시간을 알려주는 Instant 클래스 이다.

 

Instant

사람은 보통 주,날짜,시간, 분으로 날짜와 시간을 계산한다. 하지만 기계에서는 이와 같은 단위로 시간을 표현하기 어렵다

기계의 관점에서는 연속된 시간에서 특정 지점을 하나의 큰 수로 표현하는 것이 가장 자연스러운 시간 표현 방법이다 

Instant 클래스는 유닉스 에포크 시간 UTC 를 기준으로 시간을 초로 표현한다. 

 

즉 사람이 알기 쉬운 날짜와 시간 API 를 사용하는 곳에서는 Instant 말고, LocalDateTime 을 사용해야 한다.

기계와 관련된 프로그래밍을 할 때는 Instant 로 필드를 작성해야 합니다. 

(Instant 는 기계 전용 유틸리티 라는 것을 기억하자)

 

저는 실무에서 결제 관련 API 를 주로 만들기에,

결제를 태우는 단말기와 포스 등등 정밀한 시간대가 필요하므로 Instant 를 사용해야 하네요. 확실히 공부를 하며 이해가 되었습니다ㅎㅎ

Instant now = Instant.now(); // 2024-05-16T01:53:40.395691Z

 

그리고 LocalDateTime 과 Instant 는 혼합해서 사용을 할 수 없다.

 

추가적으로 Instant 와 관련된, Duration, Period 클래스가 있지만 그것은 추후에 다시 다뤄보려고 합니다.

 

그렇다면 LocalDateTime 과 Instant 는 뭐가 어떻게 다른 걸까?

위에서 설명했듯이 기계 알아야하는 날짜,시간은 Instant

사람이 알아야 하는 날짜,시간은 LocalDateTime  이렇게 정리를 끝내기에는 살짝 아쉽다

 

그래서 좀 더 파헤쳐 보려고 한다.

 

 

 

결론

기계 가 날짜와 시간을 체크 해야 한다? -> Instant

사람이 알아야 한다? -> LocalDateTime

 

자바 8 이후 나온 java.time 패키지들은 불변 객체이고 멀티 쓰레드 환경에서도 안전하다 (=thread safe) 하다.

 

 

Ref : https://sujl95.tistory.com/85 
Ref : 모던 자바 인 액션 CHAPTER 12
Ref : https://sujl95.tistory.com/3
728x90