2009-10-02 107 views
7

我有一個JDBC日期列,而如果AI使用GETDATE是得到「日期」部分只2009年10月02日,但如果我使用getTimestamp我得到充分的「日期02 Oct 2009 13:56:78:890。這是令人興奮的,我想要的。JDBC時間戳和日期GMT發出

但是getTimestamp返回的'date'忽略'GMT值,假設日期; 2009年13年10月2日:56:78:890,我最終得到2009年15年10月2日:56:78:890

我的日期被保存在數據庫上+ 2GMT日期,但應用程序服務器在格林尼治標準時間2小時即落後

如何仍然可以得到我的日期是2009年13年10月2日:56:78:890

編輯

我得到的日期+2在客戶端是在GMT +2

回答

12

這就是Timestamp和MySQL中其他時態類型的區別。時間戳以UTC格式保存爲UTC time_t,但其他類型按字面存儲日期/時間,不帶區域信息。

當您調用getTimestamp()時,如果類型爲時間戳,則MySQL JDBC驅動程序將GMT時間轉換爲默認時區。它不爲其他類型執行此類轉換。

您可以更改列類型或自己進行轉換。我建議以前的做法。

+0

關鍵字** **轉換,這就是爲什麼我得到的2小時 – n002213f 2009-10-02 13:06:20

+0

我很困惑,如果轉換工作正常,不應該看他那爲2小時不到的日期,而不是更多? – wds 2009-10-02 13:55:19

+0

@wds - 檢查我的編輯和回覆 – n002213f 2009-10-02 15:04:56

4

您應該知道java.util.Date(以及java.sql.Datejava.sql.Timestamp,它們是java.util.Date的子類)不知道任何有關時區的信息,或者說,它們始終以UTC爲單位。

java.util.Date及其子類只不過是「自01-01-1970 UTC UTC」值以來的「毫秒數」的容器。

要在特定時區顯示日期,請使用java.text.DateFormat對象將其轉換爲字符串。通過調用setTimeZone()方法來設置該對象的時區。例如:

Date date = ...; // wherever you get this from 

DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 

// Make the date format show the date in CET (central European time) 
df.setTimeZone(TimeZone.getTimeZone("CET")); 

String text = df.format(date); 
0

從這個post我今天來給JDBC確實檢索時間戳的時區(我不認爲MS SQL支持這個爲好,大多數谷歌搜索結果指向甲骨文)

當JDBC getTimeStamp結論方法被稱爲它只獲取'毫秒'部分並使用服務器TimeZone(GMT)創建Date對象。

當這個Date對象被呈現給我的客戶端,它是+2 GMT時,它增加了2個小時,這是導致額外小時數的標準偏移量。

我已通過從我檢索的日期中刪除時間偏移來糾正此問題,即轉換爲真正的GMT日期。

3

那天我遇到了一個類似的問題,那就是時間分量從某些日期被截斷。

我們縮小了Oracle驅動程序版本的差異。

Oracle的常見問題有關於這個部分:


select sysdate from dual; ...while(rs.next()) 

此前9201,這將返回: 的getObject爲SYSDATE:java.sql.Timestamp中< < < < GETDATE爲SYSDATE :java.sql.Date getTimetamp for sysdate:java.sql.Timestamp

從9201開始,以下內容將被ret urned

的getObject爲SYSDATE:java.sql.Date < < < < < GETDATE爲SYSDATE:java.sql.Date >>沒有變化 getTimetamp爲SYSDATE:java.sql.Timestamp中>>沒有變化

注意:java.sql.Date沒有時間部分,而java.sql.Timestamp沒有。

通過對數據類型映射進行此更改,JDBC驅動程序從8i/9iR1升級到920x JBDC驅動程序時,某些應用程序將失敗並且/或生成不正確的結果。 爲了保持兼容性並在升級後保持應用程序正常工作,提供了兼容性標誌。開發人員現在有一些選擇:

  1. 使用oracle.jdbc.V8Compatible標誌。

默認情況下,JDBC驅動程序未檢測到數據庫版本。若要更改兼容性標誌用於處理TIMESTAMP數據類型,連接屬性

「oracle.jdbc.V8Compatible」

可以被設置爲「真」並且駕駛員的行爲,因爲它在8i中表現,901X,9 200(與尊重TIMESTAMPs)。

默認情況下該標誌設置爲'false'。在OracleConnection構造函數中,驅動程序獲取服務器版本並適當地設置兼容性標誌。

java.util.Properties prop=newjava.util.Properties(); 
prop.put("oracle.jdbc.V8Compatible","true"); 
prop.put("user","scott"); 
prop.put("password","tiger"); 
String url="jdbc:oracle:thin:@host:port:sid"; 
Connection conn = DriverManager.getConnection(url,prop); 

隨着JDBC 10.1.0.x,代替連接屬性,下面的系統屬性,可以使用:JAVA -Doracle.jdbc.V8Compatible =真.....注:該標誌是一個客戶端只有管​​理時間戳和日期映射的標誌。它不會影響任何數據庫功能。 '

'2。相應地處理Date和TimeStamp列數據類型時,請使用set/getDate和set/getTimestamp。

9i服務器支持Date和Timestamp列類型DATE映射到java.sql.Date並且TIMESTAMP映射到java.sql.Timestamp。


所以對於我的情況,我有這樣的代碼:

import java.util.Date; 
Date d = rs.getDate(1); 

隨着9i中我得到一個java.sql.Timestamp中(這是java.util.Date的子類),所以一切時髦,我有我的時間和分鐘。

但是使用10g,相同的代碼現在得到一個java.sql.Date(也是java.util.Date的一個子類,所以它仍然可以編譯),但是HH:MM是TRUNCATED !!。

第二個解決方案對我來說很簡單 - 只需用getTimestamp替換getDate,你就可以了。我想這是一個壞習慣。

+0

感謝那一個吉姆,最感謝。 – n002213f 2009-10-22 05:38:45

0
private Date convertDate(Date date1) throws ParseException { 
     SimpleDateFormat sdfFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
     String dateStr = sdfFormatter.format(date1); 
     SimpleDateFormat sdfParser = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
     sdfParser.setTimeZone(TimeZone.getTimeZone("GMT")); 
     return sdfParser.parse(dateStr); 
    }