2009-10-02 217 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); 
    }