java.util.Date
vs java.sql.Date
: 언제 어떤 것을 왜 사용해야합니까?
답변
축하합니다. JDBC : Date class handling으로 제가 가장 좋아하는 애완 동물을 맞이했습니다.
기본적으로 데이터베이스는 일반적으로 날짜, 시간 및 시간 소인 인 세 가지 형식의 날짜 시간 필드를 지원 합니다. 이것들 각각은 JDBC에 대응하는 클래스를 가지고 있으며 각각은 extendjava.util.Date
합니다. 이 세 가지 각각의 빠른 의미는 다음과 같습니다.
java.sql.Date
SQL DATE에 해당합니다. 즉 , 시, 분, 초 및 밀리 초 는 무시 하고 연도, 월, 일 을 저장 합니다. 또한sql.Date
시간대와 관련이 없습니다.java.sql.Time
SQL TIME에 해당하며 명백히 시, 분, 초 및 밀리 초 에 대한 정보 만 포함합니다 .java.sql.Timestamp
은 사용자 정의 가능한 정밀도로 나노초와 정확한 날짜 인 SQL TIMESTAMP 에util.Date
해당합니다 (밀리 초 만 지원합니다! ).
이 세 가지 유형과 관련하여 JDBC 드라이버를 사용할 때 가장 일반적인 버그 중 하나는 유형이 잘못 처리된다는 것입니다. 이 수단 sql.Date
시간대 특정는 sql.Time
현재 연도, 월, 일 등등 등등이 포함되어 있습니다.
마지막으로 어느 것을 사용해야합니까?
실제로 필드의 SQL 유형에 따라 다릅니다. , for 및 for PreparedStatement
값 #setDate()
중 하나 인 세 값 모두에 대한 세터 가 있습니다.sql.Date
#setTime()
sql.Time
#setTimestamp()
sql.Timestamp
ps.setObject(fieldIndex, utilDateObject);
실제로 사용하는 경우 util.Date
대부분의 JDBC 드라이버에 일반 유형을 제공하여 올바른 유형 인 것처럼 행복하게 삼킬 수 있지만 나중에 데이터를 요청하면 실제로 누락 된 항목이 있음을 알 수 있습니다.
나는 실제로 날짜를 전혀 사용해서는 안된다고 말하고 있습니다.
내가 말하는 것은 밀리 초 / 나노 초를 평범한 길이로 저장하고 사용중인 모든 객체 ( 필수 조다 타임 플러그 ) 로 변환하는 것 입니다. 수행 할 수있는 하나의 해키 방법은 날짜 구성 요소를 다른 하나의 장기 및 구성 요소로 저장하는 것입니다 (예 : 현재 20100221 및 154536123).이 매직 넘버는 SQL 쿼리에 사용될 수 있으며 데이터베이스에서 다른 구성 요소로 이식 가능합니다. JDBC / Java Date API 의이 부분을 완전히 피할 수 있습니다.
답변
늦은 편집 : Java 8부터는 피할 수 있거나 사용하지 java.util.Date
않아야 java.sql.Date
하며 대신 java.time
Joda 기반 패키지 를 선호 합니다. Java 8을 사용하지 않는 경우 원래 응답은 다음과 같습니다.
java.sql.Date
-JDBC를 사용하는 라이브러리의 메소드 / 생성자를 호출 할 때. 아니, 그렇지. JDBC를 명시 적으로 처리하지 않는 응용 프로그램 / 모듈의 데이터베이스 라이브러리에 대한 종속성을 도입하지 않으려 고합니다.
java.util.Date
-그것을 사용하는 라이브러리를 사용할 때. 그렇지 않으면 몇 가지 이유로 가능한 한 적게 :
-
변경 가능하므로 메소드로 전달하거나 메소드에서 리턴 할 때마다 방어 사본을 작성해야합니다.
-
날짜를 잘 처리하지 못하므로 실제로 당신과 같은 사람들은 날짜 처리 수업을해야한다고 생각합니다.
-
이제 juD가 잘하지 않기 때문에 굉장히 많은
Calendar
수업이 소개되었습니다. 또한 변경 가능하고 작업하기가 끔찍하며, 선택 사항이 없으면 피해야합니다. -
Joda Time API 와 같은 더 나은 대안
이 있습니다(Java 7로 만들 수도 있고 새로운 공식 날짜 처리 API가 될 수도 있습니다– 빠른 검색 은 그렇지 않습니다).
Joda와 같은 새로운 의존성을 도입하는 것이 과도하다고 생각한다면 long
객체의 타임 스탬프 필드에 사용하는 것이 나쁘지는 않습니다.하지만 일반적으로 객체를 전달할 때 jud로 감싸거나 유형 안전과 문서로 사용합니다.
답변
사용하는 유일한 시간 java.sql.Date
은입니다 PreparedStatement.setDate
. 그렇지 않으면을 사용하십시오 java.util.Date
. 는를 ResultSet.getDate
반환한다고 java.sql.Date
말하지만 a 에 직접 할당 할 수 있습니다 java.util.Date
.
답변
나는 같은 문제가 있었다. 현재 날짜를 준비된 진술에 삽입하는 가장 쉬운 방법은 다음과 같다.
preparedStatement.setDate(1, new java.sql.Date(new java.util.Date().getTime()));
답변
tl; dr
둘 다 사용하지 마십시오.
java.time.Instant
대체java.util.Date
java.time.LocalDate
대체java.sql.Date
둘 다
java.util.Date vs. java.sql.Date : 언제, 왜 사용합니까?
이 두 클래스는 끔찍하고 디자인과 구현에 결함이 있습니다. 전염병 코로나 바이러스 처럼 피하십시오 .
대신 JSR 310에 정의 된 java.time 클래스를 사용 하십시오. 이 클래스는 날짜-시간 처리 작업을위한 업계 최고의 프레임 워크입니다. 이 대신하는 완전히 피 묻은 끔찍한 기존 클래스와 같은 Date
, Calendar
, SimpleDateFormat
, 등을.
java.util.Date
java.util.Date
첫 번째 java.util.Date
는 UTC의 순간을 나타내는 것으로, UTC에서 0 시간-분-초의 오프셋을 의미합니다.
java.time.Instant
이제로 대체되었습니다 java.time.Instant
.
Instant instant = Instant.now() ; // Capture the current moment as seen in UTC.
java.time.OffsetDateTime
Instant
java.time 의 기본 빌딩 블록 클래스입니다 . 더 유연성을 위해 사용 OffsetDateTime
으로 설정 ZoneOffset.UTC
UTC의 순간을 나타내는 : 같은 목적을 위해.
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;
당신은 사용하여 데이터베이스에이 객체를 보낼 수 PreparedStatement::setObject
와 JDBC 이후 4.2.
myPreparedStatement.setObject( … , odt ) ;
검색.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
java.sql.Date
java.sql.Date
java.sql.Date
클래스는 끔찍한 및 사용되지 않습니다.
이 클래스는 시간과 시간대가없는 날짜 만 나타냅니다. 불행히도, 디자인의 끔찍한 해킹 에서이 클래스는 java.util.Date
순간 (UTC로 날짜를 나타내는 날짜)을 나타내는 상속 합니다. 따라서이 클래스는 단순히 날짜 전용 인 것처럼 보이지만 실제로는 UTC로 암시 적으로 오프셋됩니다. 이것은 너무 많은 혼란을 야기합니다. 이 클래스를 사용하지 마십시오.
java.time.LocalDate
대신 java.time.LocalDate
시간이나 시간대 또는 오프셋없이 날짜 (년, 월, 일) 만 추적 하는 데 사용하십시오 .
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
LocalDate ld = LocalDate.now( z ) ; // Capture the current date as seen in the wall-clock time used by the people of a particular region (a time zone).
데이터베이스에 전송합니다.
myPreparedStatement.setObject( … , ld ) ;
검색.
LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
java.time에 대하여
java.time의 프레임 워크는 나중에 자바 8에 내장되어 있습니다. 이 클래스는 까다로운 기존에 대신 기존 과 같은 날짜 – 시간의 수업을 java.util.Date
, Calendar
, SimpleDateFormat
.
자세한 내용은 Oracle Tutorial을 참조하십시오 . 많은 예제와 설명을 보려면 스택 오버플로를 검색하십시오. 사양은 JSR 310 입니다.
Joda 타임 프로젝트는 지금에 유지 관리 모드 의로 마이그레이션을 조언 java.time의 클래스.
java.time 객체를 데이터베이스와 직접 교환 할 수 있습니다 . JDBC 4.2 이상을 준수 하는 JDBC 드라이버를 사용하십시오 . 문자열이 필요없고 수업이 필요 없습니다 .java.sql.*
java.time 클래스는 어디서 구할 수 있습니까?
- Java SE 8 , Java SE 9 , Java SE 10 , Java SE 11 이상 -번들로 구현 된 표준 Java API의 일부입니다.
- Java 9에는 몇 가지 사소한 기능과 수정 사항이 추가되었습니다.
- Java SE 6 및 Java SE 7
- 대부분의 java.time 기능은 ThreeTen-Backport의 Java 6 & 7로 백 포트됩니다 .
- 기계적 인조 인간
- java.time 클래스 의 최신 버전의 Android 번들 구현 .
- 이전 Android (<26)의 경우 ThreeTenABP 프로젝트 는 위에서 언급 한 ThreeTen-Backport를 채택합니다 . ThreeTenABP 사용 방법…을 참조하십시오 .
답변
Java의 java.util.Date 클래스는 특정 시점 (예 : 2013 년 11 월 25 일 16:30:45에서 밀리 초까지)을 나타내지 만 DB의 DATE 데이터 유형은 날짜 만 나타냅니다 (예 : 2013 년 11 월 25 일). 실수로 DB에 java.util.Date 오브젝트를 제공하지 못하게하기 위해 Java에서는 SQL 매개 변수를 java.util.Date로 직접 설정할 수 없습니다.
PreparedStatement st = ...
java.util.Date d = ...
st.setDate(1, d); //will not work
그러나 여전히 강제 / 의도로 그렇게 할 수 있습니다 (그러면 시간과 분은 DB 드라이버에서 무시됩니다). 이것은 java.sql.Date 클래스로 수행됩니다.
PreparedStatement st = ...
java.util.Date d = ...
st.setDate(1, new java.sql.Date(d.getTime())); //will work
java.sql.Date 객체는 특정 시점을 저장할 수 있으므로 (java.util.Date에서 쉽게 구성 할 수 있음) 몇 시간 동안 요청하면 예외가 발생합니다 ( 날짜 만). DB 드라이버는이 클래스를 인식하고 시간 동안 0을 사용합니다. 이 시도:
public static void main(String[] args) {
java.util.Date d1 = new java.util.Date(12345);//ms since 1970 Jan 1 midnight
java.sql.Date d2 = new java.sql.Date(12345);
System.out.println(d1.getHours());
System.out.println(d2.getHours());
}
답변
java.util.Date
밀리 초 단위로 특정 순간을 나타냅니다. 시간대가없는 날짜 및 시간 정보를 나타냅니다. java.util.Date 클래스는 Serializable, Cloneable 및 Comparable 인터페이스를 구현합니다. 그것은 상속 java.sql.Date
, java.sql.Time
및 java.sql.Timestamp
인터페이스.
java.sql.Date
시간 정보없이 날짜를 나타내는 java.util.Date 클래스를 확장하며 데이터베이스를 처리 할 때만 사용해야합니다. SQL DATE의 정의를 준수하려면 java.sql.Date
인스턴스와 연관된 특정 시간대에서 시간, 분, 초 및 밀리 초를 0으로 설정하여 인스턴스에 의해 랩핑 된 밀리 초 값을 ‘정규화’해야합니다.
그것은 모든 public 메소드 상속 java.util.Date
등을 getHours()
, getMinutes()
, getSeconds()
, setHours()
, setMinutes()
, setSeconds()
. 으로는 java.sql.Date
그것의 모든 시간 작업을 무시, 시간 정보를 저장하지 않는 java.util.Date
이들 방법 모두 던져 java.lang.IllegalArgumentException
자신의 구현 세부 사항에서 증거로 호출합니다.