Java Date & Time API의 문제점은 무엇입니까? [닫은]


105

Java Date및 기타 날짜 시간 관련 클래스 에 대한 부정적인 피드백을 자주 접합니다. .NET 개발자이기 때문에 나는 그것들을 사용하지 않고서는 그들에게 실제로 무엇이 잘못되었는지 완전히 이해할 수 없습니다.

아무도 이것에 대해 밝힐 수 있습니까?


답변:


142

아, 자바 Date클래스. 아마도 어디서든 어떤 언어로도 무언가를하지 않는 가장 좋은 예 중 하나 일 것입니다. 어디서부터 시작합니까?

JavaDoc을 읽으면 개발자가 실제로 좋은 아이디어를 얻었다 고 생각할 수 있습니다. 둘의 차이가 기본적으로 윤초 ( 아주 드물게 발생 함 ) 라는 사실에도 불구하고 UTCGMT 의 차이에 대해 자세히 설명합니다 .

그러나 디자인 결정은 실제로 잘 설계된 API라는 생각을 낭비하는 것입니다. 다음은 가장 좋아하는 실수입니다.

  • 밀레니엄의 마지막 10 년 동안 설계 되었음에도 불구하고 1900 년 이후로 연도를 두 자리 숫자로 표시합니다.이 진부한 결정의 결과로 Java 세계에서 문자 그대로 수백만 개의 해결 방법이 1900+ (또는 1900-)를 수행합니다.
  • 월은 인덱스가 0으로 지정되어 월 배열이 있고 13 개의 요소 배열을 사용하지 않는 놀랍도록 특이한 경우를 처리하기 위해 첫 번째에는 null. 결과적으로 0..11 (현재는 109 년의 11 월)이됩니다. 문자열로 변환하기 위해 달에 비슷한 수의 ++ 및-가 있습니다.
  • 그들은 가변적 입니다. 결과적으로 날짜를 되돌리고 싶을 때 (예 : 인스턴스 구조) 날짜 개체 자체 대신 해당 날짜의 복제본을 반환해야합니다 (그렇지 않으면 사람들이 구조를 변경할 수 있기 때문입니다).
  • 이것을 Calendar'수정'하도록 설계된는 실제로 동일한 실수를합니다. 그들은 여전히 ​​변할 수 있습니다.
  • Date는를 나타내지 DateTime만 SQL 영역의 항목을 연기하기 위해 java.sql.Date하루를 나타내는 다른 하위 클래스가 있습니다 (연관된 시간대는 없지만).
  • TimeZone와 연관된 s 가 없으므로 Date범위 (예 : '하루 종일')는 종종 자정-자정 (종종 임의의 시간대)으로 표시됩니다.

마지막으로 윤초는 일반적으로 한 시간 내에 ntp로 업데이트되는 좋은 시스템 시계에 대해 스스로를 수정한다는 점에 주목할 가치가 있습니다 (아래 링크 참조). 2 윤초 (최소 6 개월마다, 실질적으로 몇 년마다)가 도입 되어도 시스템이 계속 가동되고 실행될 가능성은 거의 없습니다. 특히 코드의 새 버전을 때때로 재배포해야한다는 사실을 고려하면 더욱 그렇습니다. . 클래스 또는 WAR 엔진과 같은 것을 재생성하는 동적 언어를 사용하더라도 클래스 공간을 오염시키고 결국 permgen이 부족해질 것입니다.


43

Java 8에서 이전 날짜-시간 클래스를 java.time 으로 대체 한 JSR 310 은 다음과 같이 원래 JSR 에서 정당화됩니다 .

2.5 제안 된 사양에 의해 Java 커뮤니티의 어떤 요구가 해결 될 것입니까?

현재 Java SE에는 java.util.Date 및 java.util.Calendar라는 두 개의 개별 날짜 및 시간 API가 있습니다. 두 API 모두 웹 로그 및 포럼에서 Java 개발자가 사용하기 어려운 것으로 일관되게 설명되어 있습니다. 특히 둘 다 몇 달 동안 제로 인덱스를 사용하므로 많은 버그가 발생합니다. 캘린더는 주로 내부적으로 두 가지 다른 방식으로 상태를 저장하기 때문에 수년 동안 많은 버그와 성능 문제를 겪었습니다.

한 가지 고전적인 버그 (4639407)로 인해 Calendar 개체에서 특정 날짜가 생성되지 않았습니다. 일부 사용자가 정확한 생년월일을 입력하지 못하도록하는 효과가있는 일부 연도에는 날짜를 만들 수 없지만 다른 연도에는 만들 수없는 일련의 코드를 작성할 수 있습니다. 이것은 Calendar 클래스가 여름에 일광 절약 시간을 1 시간 만 늘릴 수 있었기 때문에 발생했습니다. 역사적으로 2 차 세계 대전 당시에는 2 시간을 더한 시간이었습니다. 이 버그는 현재 수정되었지만 미래의 어느 시점에서 국가에서 여름에 3 시간을 더한 일광 절약 시간을 도입하도록 선택하면 Calendar 클래스가 다시 중단됩니다.

현재 Java SE API는 다중 스레드 환경에서도 문제가 있습니다. 변경 불가능한 클래스는 상태를 변경할 수 없기 때문에 본질적으로 스레드로부터 안전하다고 알려져 있습니다. 그러나 날짜와 달력은 모두 변경 가능하므로 프로그래머가 명시 적으로 복제 및 스레딩을 고려해야합니다. 또한 DateTimeFormat의 스레드 안전성 부족은 널리 알려져 있지 않으며 많은 스레딩 문제를 추적하기 어려운 원인이되었습니다.

Java SE가 datetime에 대해 가지고있는 클래스의 문제점뿐만 아니라 다른 개념을 모델링하기위한 클래스도 없습니다. 시간대가 아닌 날짜 또는 시간, 기간, 기간 및 간격은 Java SE에서 클래스 표현이 없습니다. 결과적으로 개발자는 단위를 지정하는 javadoc과 함께 시간의 기간을 나타내는 데 자주 int를 사용합니다.

포괄적 인 날짜 및 시간 모델이 없기 때문에 많은 일반적인 작업이 예상보다 까다로워집니다. 예를 들어, 두 날짜 사이의 일수를 계산하는 것은 현재 특히 어려운 문제입니다.

이 JSR은 날짜 및 시간 (시간대 포함 및 제외), 기간 및 기간, 간격, 형식화 및 구문 분석을 포함하여 완전한 날짜 및 시간 모델의 문제를 해결합니다.


28
  • 날짜 인스턴스는 변경 가능 하며 거의 항상 불편합니다.
  • 그들은 이중적인 성격을 가지고 있습니다. 타임 스탬프와 달력 날짜를 모두 나타냅니다. 날짜 계산을 할 때 이것이 문제가된다는 것이 밝혀졌습니다.
  • 달력 데이터의 숫자 표현은 대부분의 경우 직관적이지 않습니다. 예 : getMonth()0부터 시작하고 getYear()1900부터 시작합니다 (예 : 2009 년은 109로 표시됨).
  • Date클래스 에서 기대하는 많은 기능이 누락되었습니다 .

13

전 .NET 프로그래머로서 같은 질문을했습니다. .NET의 시간 API (시간 범위, 연산자 오버로딩)는 매우 편리합니다.

먼저 특정 날짜를 만들려면 더 이상 사용되지 않는 API를 사용하거나 다음을 수행합니다.

Calendar c = Calendar.getInstance();
c.set(2000, 31, 12)

하루를 빼기 위해 당신은 악한 일을합니다.

Date firstDate = ...
Calendar c = Calendar.getInstance();
c.setTime(fistDate);
c.add(Calendar.DATE,-1);
Date dayAgo = c.getTime();

또는 더 나쁘다

Date d = new Date();
Date d2 = new Date(d.getTime() - 1000*60*60*24);

두 날짜 (일 / 주 / 개월) 사이에 얼마나 많은 시간이 지 났는지 알아 보려면 ... 더 나빠집니다.

그러나 아파치 ( )의 DateUtilsorg.apache.commons.lang.time.DateUtils 는 몇 가지 편리한 방법을 제공하며 최근에는 그것들만을 사용하고 있음을 알았습니다.

Brabster가 썼 듯이 Joda Time도 좋은 외부 라이브러리이지만 아파치는 다른 어떤 것보다 "일반적인"것처럼 보입니다 ...


방법을 알려주십시오 ( "두 날짜 사이에 얼마나 많은 시간이 경과했는지 확인하십시오")!
안톤 고골 레프

나는 쉬운 방법을 알았 으면 좋겠다 ... 윤년, 급격한 달, 그리고 평범한 날들 ...
Eran Medan

1
org.apache.commons.lang.time, 참조 : commons.apache.org/lang//api/org/apache/commons/lang/time/...
trashgod

@AntonGogolev java.time 에서 PeriodDuration클래스를 사용 하여 각각 년-월-일 및 시간-분-초 단위로 경과 시간을 계산하고 나타냅니다.
Basil Bourque

4

솔직히 말해서 Java의 Date API를 사용할 수 있습니다. 내가 본과에 대해 들어 본 문제의 대부분은 상세, 아무것도 유용 (할 여러 클래스를 포함 할 필요성과 관련 Calendar, Date, DateFormat/ SimpleDateFormat)와 같은 단순한 접근의 부족 getDayOfWeek().

Joda Time 은 Java에서 잘 알려진 대체 API이며, 왜 Joda Time 섹션에서 관심을 가질만한 실행 가능한 대안인지에 대한 몇 가지 더 많은 논증을 제공합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.