source

JDBC ResultSet: getDateTime이 필요한데 getDate와 getTimeStamp만 있습니다.

manycodes 2023. 2. 25. 21:26
반응형

JDBC ResultSet: getDateTime이 필요한데 getDate와 getTimeStamp만 있습니다.

JDBC가 있는 Oracle DB Table에서 DATETIME 열을 가져오고 싶습니다.코드는 다음과 같습니다.

int columnType = rsmd.getColumnType(i);
if(columnType == Types.DATE)
{
    Date aDate = rs.getDate(i);
    valueToInsert = aDate.toString();
}
else if(columnType == Types.TIMESTAMP)
{
    Timestamp aTimeStamp = rs.getTimestamp(i);
    valueToInsert = aTimeStamp.toString();
}
else
{
    valueToInsert = rs.getString(i);
}

먼저 열 유형을 식별해야 합니다.관심 있는 분야는 유형으로 인식됩니다.DATE: "07.05.2009 13:49:32" 형식이기 때문에 실제로는 DB 내의 DATETIME입니다.

getDate는 시간: "07.05.2009"를 단축하고 getString은 "07.05.2009 13:49:32"에 ".0"을 추가합니다.0"

물론 최종 0.0을 삭제하고 항상 getString으로 작업할 수 있지만, 이 방법은 매우 번거롭습니다.

좋은 생각 있어요?getDateTime 메서드를 찾고 있었습니다.

이 답변은 구식입니다.Basil Bourque의 답변을 계속합니다.

java.util.Date date;
Timestamp timestamp = resultSet.getTimestamp(i);
if (timestamp != null)
    date = new java.util.Date(timestamp.getTime()));

그럼 원하는 대로 포맷하세요.

Leos Literak의 답변은 정확하지만 지금은 오래된 날짜 수업 중 하나를 사용하여 시대에 뒤떨어져 있다.java.sql.Timestamp.

dr;dr

DB의 DATETIME입니다.

아,, 그그않않않않.다음과 같은 데이터 유형이 없습니다.DATETIME오라클

getDateTime 메서드를 찾고 있었습니다.

JDBC 4.2 이후의 java.time 클래스는 질문에서 볼 수 있는 번거로운 레거시 클래스가 아니라 사용합니다.특히나,java.sql.TIMESTAMP하다, 사용하다Instant SQL과 TIMESTAMP WITH TIME ZONE.

조작된 코드 조각:

if( 
    JDBCType.valueOf( 
        myResultSetMetaData.getColumnType( … )
    )
    .equals( JDBCType.TIMESTAMP_WITH_TIMEZONE ) 
) {
    Instant instant = myResultSet.getObject( … , Instant.class ) ;
}

이상하게도 JDBC 4.2 사양에서는 가장 일반적으로 사용되는2개의 java.time 클래스에 대한 지원이 필요하지 않습니다.Instant ★★★★★★★★★★★★★★★★★」ZonedDateTime하시는 JDBC가하지 않는 JDBC를 OffsetDateTime★★★★★★ 。

OffsetDateTime offsetDateTime = myResultSet.getObject( … , OffsetDateTime.class ) ;

세부 사항

JDBC가 있는 Oracle DB Table에서 DATETIME 열을 가져오고 싶습니다.

문서에 따르면 열 데이터 유형이 없습니다.DATETIME오라클이 용어는 Oracle의 모든 날짜 유형을 그룹으로 지칭하는 용어인 것 같습니다.

데이터 타입의 타입과 브랜치를 검출하는 코드의 포인트를 알 수 없습니다.일반적으로, 특정 테이블과 특정 비즈니스 문제에 대해 명시적으로 코드를 작성해야 한다고 생각합니다.아마도 이것은 일종의 일반적인 프레임워크에서 유용할 것이다.만약 당신이 원한다면, 다양한 타입에 대해, 그리고 당신의 질문에 사용된 클래스를 대체하는 Java 8과 그 이후에 내장된 매우 유용한 새로운 java.time 클래스에 대해 알아보려면 계속 읽어보십시오.

스마트한 오브젝트, 바보 같은 문자열

valueToInsert = aDate.toString();

값을 로 교환하려고 .String 하지 마세요.지지마 。

데이터베이스와 날짜 시간 값을 교환하려면 날짜 시간 개체를 사용합니다.Java 8 이후에서는 다음과 같이 java.time 객체를 의미합니다.

다양한 시스템

날짜 시간 관련 데이터 유형 세 가지를 혼동할 수 있습니다.

  • 표준 SQL 유형
  • 독자적인 타입
  • JDBC 타입

SQL 표준 유형

SQL 표준에는 다음 5가지 유형이 정의되어 있습니다.

  • DATE
  • TIME WITHOUT TIME ZONE
  • TIME WITH TIME ZONE
  • TIMESTAMP WITHOUT TIME ZONE
  • TIMESTAMP WITH TIME ZONE

날짜만

  • DATE
    날짜만, 시간대와 시간대는 없습니다.

Time-Of-Day만

  • TIME ★★★★★★★★★★★★★★★★★」TIME WITHOUT TIME ZONE
    시간만 있고 날짜는 없습니다.입력의 일부로 지정된 시간대를 자동으로 무시합니다.
  • TIME WITH TIME ZONE (오류)TIMETZ)
    시간만 있고 날짜는 없습니다.입력에 충분한 데이터가 포함되어 있는 경우 시간대 및 일광 절약 시간 규칙을 적용합니다.Postgres 문서에서 설명한 바와 같이 다른 데이터 유형을 고려할 때 유용성이 의심스럽다.

날짜와 시각

  • TIMESTAMP ★★★★★★★★★★★★★★★★★」TIMESTAMP WITHOUT TIME ZONE
    날짜와 시각. 단, 타임존은 무시됩니다.데이터베이스에 전달되는 모든 시간대 정보는 UTC에 대한 조정 없이 무시됩니다.따라서 이는 타임라인상의 특정 순간을 나타내는 것이 아니라 약 26~27시간에 걸쳐 발생할 수 있는 일련의 순간을 나타냅니다.시간대 또는 오프셋이 불분명하거나 (b) "전 세계 모든 공장이 점심시간으로 정오에 문을 닫습니다"와 같이 관련이 없는 경우 사용합니다.의심스럽다면 별로 좋은 타입이 아닐 겁니다.
  • TIMESTAMP WITH TIME ZONE (오류)TIMESTAMPTZ)
    시간대에 관한 날짜와 시각.이 이름은 구현에 따라 다소 잘못된 명칭이 됩니다.일부 시스템에서는 지정된 시간대 정보를 저장할 수 있습니다.Postgres 등의 다른 시스템에서는 시간대 정보가 저장되지 않고 대신 데이터베이스에 전달된 시간대 정보를 사용하여 날짜 시간을 UTC로 조정합니다.

독자 사양

대부분의 데이터베이스는 고유한 날짜 관련 유형을 제공합니다.독자적인 타입은 매우 다양합니다.일부는 오래된 레거시 유형으로 피해야 합니다.벤더에 의해 특정 이점이 있다고 생각되는 제품도 있습니다.표준 유형만 사용할지 여부는 사용자가 결정합니다.주의:일부 독점 유형은 표준 유형과 이름이 충돌합니다. Oracle을 보고 있습니다.

JDBC

Java 플랫폼의 내부 세부 정보는 SQL 표준 또는 특정 데이터베이스와 다르게 처리됩니다.JDBC 드라이버의 역할은 이러한 차이를 조정하고 브리지 역할을 하며 필요에 따라 유형과 실제 구현된 데이터 값을 변환하는 것입니다.java.sql.* 패키지는 그 브릿지입니다.

JDBC 레거시클래스

Java 8 이전 JDBC 사양에서는 날짜 작업용으로 3가지 유형을 정의했습니다.첫 번째 2개는 버전8 이전과 같은 해킹입니다.Java에는 날짜 전용 또는 시간 전용 값을 나타내는 클래스가 없었습니다.

  • sql.sql 입니다.
    날짜만 시뮬레이션하고 시간이나 시간대가 없는 것처럼 가장합니다.이 클래스는 java.util을 둘러싼 래퍼이기 때문에 혼란스러울 수 있습니다.날짜와 시간을 모두 추적하는 날짜입니다.내부적으로 시간 부분은 0(자정 UTC)으로 설정됩니다.
  • sql.sql 입니다.
    시간만, 날짜도 시간대도 없는 것처럼 가장합니다.이 클래스도 java.util의 얇은 래퍼이기 때문에 혼란스러울 수 있습니다.날짜와 시간을 모두 추적하는 날짜입니다.내부적으로 날짜는 0(1970년 1월 1일)으로 설정되어 있습니다.
  • sql.sql 입니다.
    날짜 및 시간은 지정되지만 표준 시간대는 지정되지 않습니다.java.java.java를 사용하다

그러면 ResultSet 인터페이스에 "getDateTime" 메서드가 없다는 질문에 대한 답변이 나옵니다.이 인터페이스는 JDBC에서 정의된3가지 브리징데이터 타입에 대해 getter 메서드를 제공합니다.

번째 에는 offset-from-UTC의개념이 .은 ★★★★★★★★★★★★★★★★★.java.sql.Timestamp는 UTC에 항상 포함되어 있습니다.toString법이알알 알알알다다

JDBC 모던 클래스

위의 JDBC 클래스는 설계가 불량한 것은 피해야 합니다.이러한 유형은 java.time 유형으로 대체됩니다.

  • java.sql.Date하다, 사용하다LocalDate .SQL에 적합DATEdiscloss.discloss.
  • java.sql.Time하다, 사용하다LocalTime .SQL에 적합TIME WITHOUT TIME ZONEdiscloss.discloss.
  • java.sql.Timestamp하다, 사용하다Instant .SQL에 적합TIMESTAMP WITH TIME ZONE 유형.

JDBC 4.2 이후에서는 데이터베이스와 java.time 개체를 직접 교환할 수 있습니다.사용하다setObject/getObject★★★★★★★★★★★★★★★★★★.

삽입/갱신.

myPreparedStatement.setObject( … , instant ) ;

취득.

Instant instant = myResultSet.getObject( … , Instant.class ) ;

클래스는 타임라인상의 순간을 UTC로 나노초(10진수의 최대 9자리)의 분해능으로 나타냅니다.

Adjusting time zone

그 순간을 보고 싶다면Instant 특정 볼 때 UTC를 합니다.ZoneIdZonedDateTime★★★★★★ 。

ZoneId zAuckland = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdtAuckland = instant.atZone( zAuckland ) ;

결과, 「」가 됩니다.ZonedDateTime오브젝트는 타임라인상의 같은 순간, 같은 동시 지점입니다.동쪽에 새로운 날이 일찍 밝기 때문에 날짜와 시간이 다릅니다.예를 들어, 뉴질랜드에서는 자정 몇 분 후가 UTC로 여전히 "어제"입니다.

할 수 있습니다.Instant ★★★★★★★★★★★★★★★★★」ZonedDateTime다른 지역의 사람들이 사용하는 또 다른 벽시계 시간을 통해 동일한 동시 순간을 볼 수 있습니다.

ZoneId zMontréal = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdtMontréal = zdtAuckland.withZoneSameInstant( zMontréal ) ;  // Or, for the same effect: instant.atZone( zMontréal ) 

, 세 가지 사물사물 3가지 사물이 .instant,zdtAuckland,zMontréal는 모두 는 모두 타임라인상의 같은 순간, 같은 점을 나타냅니다.

탐지 유형

(내 ( 위에서와 같이 싶다.또 이것을 8로는 (a)의 「데이터 타입 검출」에 .java.sql.Types클래스가 구식입니다.이 클래스는 새로운 인터페이스를 구현하는의 적절한 Java로 대체되었습니다.관련 질문에 대한 답변을 참조하십시오.

이 변경은 JDBC Maintenance Release 4.2 섹션3 및 4에 기재되어 있습니다.견적 내용:

java.sql 추가.JDBCType 열거형

JDBC 유형이라고 하는 일반 SQL 유형을 식별하는 데 사용되는 Enum입니다.목적은 JDB를 사용하는 것입니다.Types.java에 정의된 상수 대신 CType을 사용합니다.

enum의 값은 이전 클래스와 동일하지만 이제 유형 안전성을 제공합니다.

구문에: 에서는 "Java"를할 수 .switch Enum.따라서 질문에서 보듯이 캐스케이드 if-then 문장을 사용할 필요가 없습니다.객체의 이 어떤 될 때 되어야 하기 에 enum 객체의 이름을 입니다.아, 아, 아, 아, 아, 아, 아, 아, 아, 아.switchTIMESTAMP_WITH_TIMEZONEJDBCType.TIMESTAMP_WITH_TIMEZONE아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아.static import★★★★★★ 。

즉, (아직 시도하지 않았습니다) 다음과 같은 코드 예를 사용할 수 있습니다.

final int columnType = myResultSetMetaData.getColumnType( … ) ;
final JDBCType jdbcType = JDBCType.valueOf( columnType ) ;

switch( jdbcType ) {  

    case DATE :  // FYI: Qualified type name `JDBCType.DATE` not allowed in a switch, because of an obscure technical issue. Use a `static import` statement.
        …
        break ;

    case TIMESTAMP_WITH_TIMEZONE :
        …
        break ;

    default :
        … 
        break ;

}

여기에 이미지 설명 입력


java.time 정보

java.time 프레임워크는 Java 8 이후에 포함되어 있습니다.이러한 클래스는 , 및 등 문제가 많은 오래된 레거시 날짜 시간 클래스를 대체합니다.

현재 유지보수 모드에 있는 조다 타임 프로젝트는 java.time 클래스로의 이행을 권장합니다.

자세한 내용은 Oracle 자습서를 참조하십시오.또한 Stack Overflow를 검색하여 많은 예와 설명을 확인하십시오.사양은 JSR 310입니다.

java.time 객체를 데이터베이스와 직접 교환할 수 있습니다.JDBC 4.2 이후준거한JDBC 드라이버를 사용합니다.스트링도 필요 없고java.sql.*②.

java.time 클래스는 어디서 얻을 수 있습니까?

쓰리텐 엑스트라 프로젝트는 java.time을 추가 클래스로 확장합니다.이 프로젝트는 향후 java.time에 추가될 수 있는 가능성을 입증하는 기반입니다.여기에는 , , , 유용한 클래스가 있습니다.


업데이트: 현재 유지보수 모드에 있는 Joda-Time 프로젝트는 java.time 클래스로의 이행을 권장합니다.이 부분은 그대로 역사로 남았습니다.

조다 타임

Java 8 이전(java.time).* package), java(package.date-time classs)에 번들되어 있습니다.날짜 & 캘린더, java.text.SimpleDateFormat)은 번거롭고 혼란스러우며 결함이 있는 것으로 알려져 있습니다.

JDBC 드라이버가 제공하는 것을 가져와 Joda-Time 객체를 생성하거나 Java 8의 java.time을 생성하는 것이 좋습니다.* 패키지최종적으로 새로운 java.time을 자동으로 사용하는 새로운 JDBC 드라이버가 표시됩니다.* 클래스그 전까지는 java.sql 등의 클래스에 메서드가 추가되어 있습니다.및 등 java.time에 삽입하는 타임스탬프fromInstant.

스트링

질문의 후반부에 대해서는 String 렌더링...포맷터 오브젝트를 사용하여 문자열 값을 생성해야 합니다.

구식 방법은 java.text를 사용하는 것입니다.SimpleDateFormat.권장하지 않습니다.

Joda-Time은 다양한 내장 포맷을 제공하며, 사용자 자신의 포맷을 정의할 수도 있습니다.그러나 말씀하신 대로 로그 또는 보고서를 작성할 경우 ISO 8601 형식을 선택하는 것이 가장 좋습니다.이 형식은 Joda-Time 및 java.time에서 사용되는 기본값입니다.

코드 예시

//java.sql.Timestamp timestamp = resultSet.getTimestamp(i);
// Or, fake it 
// long m = DateTime.now().getMillis();
// java.sql.Timestamp timestamp = new java.sql.Timestamp( m );

//DateTime dateTimeUtc = new DateTime( timestamp.getTime(), DateTimeZone.UTC );
DateTime dateTimeUtc = new DateTime( DateTimeZone.UTC ); // Defaults to now, this moment.

// Convert as needed for presentation to user in local time zone.
DateTimeZone timeZone = DateTimeZone.forID("Europe/Paris");
DateTime dateTimeZoned = dateTimeUtc.toDateTime( timeZone );

콘솔에 덤프...

System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "dateTimeZoned: " + dateTimeZoned );

실행 시...

dateTimeUtc: 2014-01-16T22:48:46.840Z
dateTimeZoned: 2014-01-16T23:48:46.840+01:00

이 기능은 다음과 같습니다.

    Date date = null;
    String dateStr = rs.getString("doc_date");
    if (dateStr != null) {
        date = dateFormat.parse(dateStr);
    }

SimpleDateFormat을 사용합니다.

제가 선택한 솔루션은 mysql 쿼리로 날짜를 포맷하는 것이었습니다.

String l_mysqlQuery = "SELECT DATE_FORMAT(time, '%Y-%m-%d %H:%i:%s') FROM uld_departure;"
l_importedTable = fStatement.executeQuery( l_mysqlQuery );
System.out.println(l_importedTable.getString( timeIndex));

나도 똑같은 문제가 있었어.에는 mysql 2017-01-01 21:02:50

String l_mysqlQuery = "SELECT time FROM uld_departure;"
l_importedTable = fStatement.executeQuery( l_mysqlQuery );
System.out.println(l_importedTable.getString( timeIndex));

은 날짜 하고 있었습니다: 음 : was 、 음 、 was 、 was 、 was was was was was was was was 。2017-01-01 21:02:50.0

언급URL : https://stackoverflow.com/questions/21162753/jdbc-resultset-i-need-a-getdatetime-but-there-is-only-getdate-and-gettimestamp

반응형