자바에서 시간설정을 할때, 자바에서 기본 제공해주는 java.util.Date 클래스나 java.util.Calendar 클래스를 사용하기 보다는 Joda-Time 클래스를 사용할 것을 권장하는 이유에 대해 알아보고자 합니다.

zumgu_profie

시작하며

회사에 신입으로 입사를 하고 파일럿 프로젝트를 진행하며, java.util.Date, java.util.Calendar 클래스를 사용하지 말고 Joda-Time 을 사용하라고 권장하셨습니다. 학부시절에는 당연히 자바에서 제공해주는 시간 클래스를 사용하였기에 Joda-Time이 익숙해지기는 조금 시간이 걸렸던 것 같습니다.

왜 사용해야 하는지 이유를 모르고 사용하였기에 익숙해지는 시간이 더 걸렸을 수도(?) 있었다는 생각이 들기도 합니다. 오늘 출근길에 그 이유에 대해 드디어(?) 알게되어 간략하게 기록해두고자 포스팅을 하게 되었습니다.

yoda

조다(요다?!) 타임의 사용 이유를 알아봅시다!

java.util.Date, java.util.Calendar 클래스의 문제점

많은 회사에서 JDK 기본 날짜 클래스를 권장하지 않고 Joda-Time과 같은 날짜 클래스를 사용하기를 권장하는데는 JDK 기본 날짜 클래스가 기본적으로 많은(?) 문제점을 가지고 있기 때문입니다. (Joda-Time이 생긴 이유도 개발자들이 JDK 기본 날짜 클래스를 사용하다 많은 문제점으로 인해 사용이 불편해서 만들었다고 하네요…)

간략히 요약하자면 JDK 기본 날짜 클래스에는 아래와 같은 문제점이 있다고 합니다. (‘네이버를 만든기술 -자바편’을 보고 정리합니다.)

  1. 불변 객체가 아니다.
  2. 상수 필드의 남용
  3. 헷갈리는 월(Month) 지정
  4. 일관성 없는 요일 상수

책에서는 이외에도 몇가지 문제점이 더 있다고 설명하고 있는데, 제가 책을 읽으며 판단하기에 이건 진짜 불편하겠다 싶은 문제점만 요약했습니다. 그럼 하나하나 위에서 설명한 문제점에 대해 말씀드리고자 합니다.

1. 불변 객체가 아니다.

JDK 기본 날짜 클래스에서는 시간을 설정할 수 있는 setter 기능을 제공하고 있습니다. 일반적으로 생각할때, 날짜 관련 클래스는 불변객체(immutable object) 이여야 합니다.(VO는 완전한 불변 객체일 때 별칭 문제, 스레드 불안정성 등의 부작용에서 자유롭고 여러 객체에서 공유해도 안전합니다.) 만일 설정이 가능하다면 시간 객체가 복사된 객체가 생성되어야겠지요.

이처럼 JDK 기본 날짜 클래스가 불변 객체가 아니기 때문에 Date 객체나 Calendar 객체가 여러 객체에서 공유되면 한 곳에서 바꾼 값이 다른 곳에 영향을 미치는 부작용이 생길 수 있습니다.

2. 상수 필드의 남용

회사에서 코드리뷰를 할 때에도 상수의 사용은 되도록 피하도록 선배분들께서 많이 조언해주십니다. 상수를 남용해서 사용하게 되면 그 코드를 작성한 개발자만 그 의미를 파악할 수 있고 다른 개발자가 해당 코드를 수정 할 일이있다면 그 의도를 파악하는데 많은 시간을 허비하게 되기 때문입니다.(매직넘버를 사용하지 말것을 권장합니다.)

그런데 Calendar 클래스를 사용한 날짜 연산은 상수 필드를 사용하게 끔 되어 있습니다.

// 초 더하기 코드

/*만일 첫번째 매게변수에 calendar.JUNE 과 같은 값이 들어가면 엉뚱한 결과가 나올 것입니다. */
calendar.add(Calendar.SECOND, 2);

3. 헷갈리는 월(Month) 지정

Date 클래스는 월의 시작을 0부터 시작하게 되어있습니다.

yoda

위의 그림에서처럼 1월은 0, 2월은 1 … 12월은 11로 설정하도록 되어있습니다. 공식 문서에서도 쓰지말라고 @Deprecated(더 이상 지원하지 않겠다.) 되어있는것을 보실 수 있네요…(쓰지마세요..)

일반적으로 이러한 헷갈리는 월 지정은 많은 개발자들을 헷갈리게 할 것입니다.

4. 일관성 없는 요일 상수

위에서 설명드린것 처럼 월의 지정은 0 부터 시작한다고 말씀드렸는데요. 자바의 Calendar 클래스에서 요일의 설정은 또 1부터 시작합니다. ()일요일은 1, 월요일은 2, 화요일은 3 …) 그런데 Date 객체를 사용하면 일요일은 또 0부터 시작하게 됩니다. 이처럼 일관성 없는 요일 상수로 인해 많은 개발자들은 불편함을 겪게 될 것입니다.

Joda-Time을 사용합시다!

위에서 설명했듯이 JDK 날짜 클래스는 잘못 사용하거나 혼동의 여지가 많이 있습니다. 이러한 문제 때문에 많은 분들이 Joda-Time과 같은 날짜 클래스를 사용할 것을 권장하고 있습니다. (Time and Money Code Library, CalendarDate, date4j 등 개선된 다른 날짜 클래스들도 있다고 합니다.)

Joda-Time은 아래와 같은 특징이 있다고 합니다.

  • LocalDate, DateTime 등으로 지역 시간과 시간대가 지정된 시간을 구분
  • plusDays, plusMinutes, plusSeconds 등 단위별 날자 연산 메서드를 LocalDate 클래스와 DateTime 클래스에서 지원한다.
  • 월의 int 값과 명칭이 일치한다.
  • 13월 같이 잘못된 월이면 IllegalFieldValueExcption을 반환한다.
  • 요일 상수가 전체 라이브러리에서 일관성있게 적용된다.

마치며

이제서야 JDK 기본 날짜 클래스의 사용을 피하라고 선배 개발자분들이 말씀하신지 이유를 알게되었습니다. 스프링프레임워크나 하이버네이트에서도 Joda-Time을 기본으로 지원을 하기 때문에 JDK 기본날짜 클래스의 사용보다는 Joda-Time을 사용하는 습관을 들이도록 노력해야겠습니다.

기회가 된다면 Joda-Time의 사용법에 대해서도 공부하며 정리해보면 좋겠습니다.