Date < jodaTime < LocalDate
Date, Calendar 라는 JDK 기본 날짜 API 의 여러 문제점으로 인해, 개발자들은 자바 표준 라이브러리가아닌 jodaTime 이라는 API 를 사용하기 시작하였고, 자바에서 이를 해결하기위해 개발한 클래스가 LocalDate 이다
불변객체 (immutable object) 가 아니다.
Date 의 시간을 setter 메서드를 통해 변경가능하다.
이는 가변객체가 가지는 모든 단점을 가지게 된다. (비동기 처리시 데이터 무결성 침해 등)
상수 필드의 남용
calendar.add(Calendar.SECOND, 2);
여기서, 첫 파라미터에 Calendar.JUNE 같이 엉뚱한 상수가 들어가더라도, Compile 시점에서 확인할 수 없다.
또한 int 상수가 너무 많아 후술할 3, 4번 문제에서에서도 혼란을 유발시킨다.
N - 1 월
Date, Calendar 는 월 지정시 N월을 N-1 월 즉 0부터 시작하는 상수로 대입한다. 즉, 10월을 표현하고 싶다면 9 또는 10 - 1 로 표현해야한다는 것 이다.
일관성 없는 요일 상수
Calendar.get(..)
에서 반환한 요일은 일요일을 1로 표현하는 int 값을 반환하나, calendar.getTime()
으로 얻은 Date 객체의 요일을 구하는 메서드인 getDay()
를 호출하면 일요일을 0으로 표현하는 int 값을 반환한다.
즉, Calendar 와 Date 간의 요일 상수가 불일치한다
또한, Date.getDay() 라는 이름 또한 매우 모호하다 (현재 deprecated 됨)
Date, Calendar 의 역할분담
실제로 날짜를 저장하는 Model 은 Date 이지만, 특정 시간대의 날짜를 생성하거나, 년/월/일 등의 날짜 해석은 Calendar 에서 해야하며, 이후 Calendar 에서 다시 Date 객체를 생성해야한다.
즉, 프로세스가 복잡하고, 생성비용이 복잡한 Calendar 를 써야하기에 비효율적이다.
non validation TimeZone
TimeZone
객체 생성시, getTimeZone()
의 인자로 받아들이는 timeZone 문자열에 대한 어떠한 검증도 없다. 따라서 찾기 어려운 버그가 발생하기 쉽다
Date extends Date
java.util.Date 를 상속한 java.sql.Date 클래스가 상위클래스와 이름이 같다.
심지어, sql.Date 는 Comparable 인터페이스의 정의를 선언하지 않았기 때문에, Comparable 관련 Generics 선언이 복잡해진다.
이러한 문제를 해결하기 위해 java8
부터는 LocalDate, LocalTime, LocalDateTime 이라는 클래스를 만들어 더욱 편리한 날짜 및 시간 API 를 제공하였다
또한 세 클래스 모두 now()
와 of()
라는 static method 를 사용하여 편리하게 객체를 생성할 수 있으며,
날짜의 덧셈은 plusXXX()
, 뺄셈은 minusXXX()
라는 직관적인 네이밍의 메서드를 지원하고
시간 비교 또한 isBefore(..)
isAfter(..)
를 통해 편하게 가능하다.
또한 getXXX()
메서드를 통해 년/월/일 해석 또한 가능하다