2012-10-30 4 views
5

버그가 있은 후 밀리 초가 걸리는 생성자를 사용하여 java.util.Date에서 java.sql.Timestamp를 생성하면 Date 인스턴스가 항상 타임 스탬프 (after)임을 알 수있었습니다. (a) before()에 대한 계약이 엄격한 비교를 지정하고 (b) 같지 않은 경우 Timestamp는 나노초를 가졌기 때문에 날짜 자체 이후 일 수 있습니다. 그러나 결과는 반대이고 반복 가능합니다 (JDK 1.6 및 1.7, JVM 시간대가 다름). 두 날짜를 비교하면 올바르게 작동하지만 Date에서 before() 또는 after()를 호출하고 Timestamp 인수를 지정하면 예기치 않은 결과가 발생합니다.java.util.Date에서 생성 된 java.sql.Timestamp는 항상 before()입니까?

아래 샘플 코드는 두 개의 Date와 Timestamp 인스턴스를 가지며, 모두 밀리 초 값이 같습니다. 그러나 Date와 Timestamp를 비교하면 Date가 after() 인 시간이 표시됩니다.

import java.util.Date; 
import java.sql.Timestamp; 

public class X extends Date { 

    public static void main(String[] args) { 
     Date d1 = new Date(); 
     Date d2 = new Date(d1.getTime()); 
     Timestamp t = new Timestamp (d1.getTime()); 
     System.out.println ("date1 = " + d1 + " (" + d1.getTime() + ")"); 
     System.out.println ("date2 = " + d2 + " (" + d2.getTime() + ")"); 
     System.out.println ("timestamp = " + t + " (" + t.getTime() + ")"); 
     System.out.println ("d1 before d2: " + d1.before(d2)); 
     System.out.println ("d1 after d2: " + d1.after(d2)); 
     System.out.println ("d1 before ts: " + d1.before(t)); 
     System.out.println ("d1 after ts: " + d1.after(t)); //why true? 
    } 
} 

샘플 출력 :

C:\>\Java\jdk1.7.0_05\bin\java X 
date1 = Tue Oct 30 10:15:59 EDT 2012 (1351606559812) 
date2 = Tue Oct 30 10:15:59 EDT 2012 (1351606559812) 
timestamp = 2012-10-30 10:15:59.812 (1351606559812) 
d1 before d2: false 
d1 after d2: false 
d1 before ts: false 
d1 after ts: true 

마지막 줄 호기심이다.

감사합니다. 당신이 내부 표현을보고 무엇을 after() 방법으로 비교하는 경우

+0

디버거를 사용하여이를 가리 킵니다. [Timestamp API] (http://docs.oracle.com/javase/6/docs/api/java/sql/Timestamp.html) * "[...]를 사용하면 타임 스탬프 값을 볼 수없는 코드를 권장합니다. 일반적으로 java.util.Date의 인스턴스로 사용됩니다. "* – Kai

+1

'd1.compareTo (ts);는 결과가 1이고, 1 나노 차이 또는 그와 비슷한 것이 있음을 나타냅니다. ___ 나는 그것이 버그라고 믿습니다. 그렇습니다. 그것을 찾는 멋진 직업! – XenoRo

답변

6

, 당신은 예를 들어

millis = 1351607849957 

당신이 Date

fastTime = 1351607849957 

Timestamp

로 얻을 참조
fastTime = 1351607849000 
nanos = 957000000 

비교되는 부분은 모두 fastTime 부분이므로 관찰 된 동작을 얻을 수 있습니다. @ user714965는 위에서 지적한 것처럼 TimestampDate으로 처리하지 않아야합니다.

+0

아, 이거 야. 고맙습니다. –

4

java.sql.Timestamp의 API 문서는 말한다 :

참고 :이 유형은 java.util.Date 별도의 나노 값의 복합체입니다. 적분 초만 java.util.Date 구성 요소에 저장됩니다. 분수 초 - 나노는 분리되어 있습니다.

(Keppil의 답변에 동의합니다).

또한 말한다 :

인해 Timestamp 클래스와 위에서 언급 한 java.util.Date 클래스 사이의 차이, 그 코드가 java.util.Date의 인스턴스로 일반적으로 Timestamp 값을 볼 수 없습니다 좋습니다. Timestampjava.util.Date 사이의 상속 관계는 실제로 상속을 나타내며 상속을 나타냅니다.당신은 당신이 방법은 기대 (java.util.Date.after()에 전달 경우에 당신이하고있는 일입니다 java.util.DateTimestamp을 취급하지 말아야 의미

java.util.Date - 당신은이를 인 것처럼 그것을 치료하는 Timestamp에 전달하는 java.util.Date,이 주석은하지 말아야 함).

이것은 표준 Java 라이브러리에서 잘못된 디자인입니다. 날짜와 시간으로 작업해야하는 경우 훨씬 더 설계되고 강력한 라이브러리 인 Joda Time을 사용하십시오.

+0

그래, 난 그 차이 (그리고 비호 환성, 특히 equals())뿐만 아니라 조다 알고 있지만이 이상한 행동에 대한 설명을 찾고 있어요. –

+0

java.sql.Timestamp와 같은 클래스의 소스 코드를 파고들 수 있습니다. JDK 설치 디렉토리에있는'src.zip '파일에서 찾을 수 있습니다. – Jesper

관련 문제