[Java] Java의 날짜, 시간 클래스는 어떻게 편해졌나
Java 1.7까지는 기본 SDK에서 날짜와 시간을 표현하고 사용하기 위해서는 java.util.Date 클래스와 java.util.Calendar 클래스를 이용해야 했습니다. 하지만 아주 잠깐만 사용해봐도 어마어마하게 불편하다는 것을 알 수 있습니다.
그래서 나온것이 Joda-Time이라는 오픈소스 라이브러리였고 Java 8에서는 드디어 개선되어서 적용되었습니다.
그러면 어떻게 좋지 않았고 어떠한 사항이 개선되었는지 확인해보겠습니다.
우선 아주 잘 정리된 Naver D2의 게시글을 공유해드립니다. 저의 게시글은 아래 링크의 글에 기반으로 한 글입니다. 그런데 정리를 곁들인.
d2.naver.com/helloworld/645609
1. JDK 1.8 미만의 날짜 계산 단점
사용시 착오가 생길 수 있는 부분들이 여럿 있었습니다. 물론 SDK 자체의 오류는 아니고 시간이 영향을 받는 제도들 때문이였습니다.
- UTC 기준 1582년 10월 4일에 Calendar.add(Calendar.DATE, 1); 로 더하면 10월 15일이 된다.
- 실종된 10일은 그레고리력을 처음 적용하면서 생긴 오차이다.
- Asia/Seoul 기준 1988년 5월 7일 23시에 Calendar.add(Calendar.HOUR_OF_DAY, 1); 로 더하면 5월 8일 새벽 1시가 된다.
- 이 시기에 적용된 일광절약시간제(서머타임) 때문이다. 서버타임인지는 TimeZone.inDaylightTime() 메서드로 확인할 수 있다.
- ...
즉, JDK 1.8 미만의 기본 날짜 클래스의 문제점 중의 하나는 고려할 점이 많고 배경지식이 필요하다는 점입니다.
이제 인지적 문제점 말고 기능적 문제점들을 정리해보겠습니다.
- 불변 객체가 아니다
- int 상수 필드의 남용
- 헷갈리는 월 지정 ( 0 부터 시작 )
- Calendar와 Date의 일치하지 않는 요일 상수
- 불필요하게 나눠진 Date, Calendar 클래스의 역할
- 오류에 둔감한 시간대 ID 지정
- java.util.Date 하위 클래스인 java.sql.Date 클래스의 이름 중복
- java.sql.TimeStamp 클래스와 java.util.Date 클래스의 equals() 선언의 비대칭성
여러 문제점이 있지만 직접 사용해 본 경험에서 가장 힘든건 불필요하게 나눠진 클래스의 역할이였습니다. 불필요하게 Calendar 객체 혹은 Date 객체를 생성해야했고 날짜에 대해서 복잡한 로직을 개발하다 보면 코드가 매우 지저분해지고 꼬이는 일이 많이 발생했습니다.
2. Joda Time의 개선점
- LocalDate, DateTime 등으로 시간대를 지정하지 않은 시간을 구분
- LocalDate와 LocalTime으로 날짜와 시간 클래스 구분
- 단위별 날짜 연산 메서드를 지원하고 각 메서드에서 호출된 객체의 상태를 변경하지 않는다. (불변객체)
- 월 지정을 명확히 했다. ( 1부터 시작 )
- 잘못된 월이 들어가면 객체 생성 시점에 IllegalFieldValueException을 발생시킨다.
- 요일 상수가 일관됨
- 잘못된 시간대 지정시 IllegalArguementException 발생시킨다.
위에서 기존에 단점으로 제시된 부분들을 대부분 보완하고 있습니다.
3. JSR-310: 새로운 Java의 날짜 API의 개선점
기존의 Joda Time으로부터 많은 영향을 받은 만큼 Joda Time을 다듬은 수준의 장점을 가지고 있습니다. 물론 라이브러리를 추가하지 않고 사용할 수 있다는게 가장 큰 장점이겠네요
- DateTime 클래스 대신 ZoneDateTime 클래스를 사용하여 기능에 대한 명칭을 명확히 하였다.
- 요일 클래스를 Enum 상수로 제공합니다. 더는 혼동할 여지를 주지 않습니다.
- 생성자 대신 static 메서드를 주로 사용하도록 제공합니다. 가독성이 높아지고 생성된 객체를 재활용 할 수 있도록 합니다.
- Joda Time 보다 클래스별 역할이 더 세분화 되었습니다.
- JodaTime에서 잘못된 월, 잘못된 시간대 지정시 발생한 Exception들보다 명확한 명칭의 Exception을 사용한다.
잘못 지정된 시간대 - ZoneRulesException, 잘못된 월 지정 - DateTimeException - 나노초까지 다룰 수 있다. ( Joda Time은 밀리초까지 )