过去2天内以Java 1.7.0运行的SQL Server中的日期列(MSSQL-JDBC 3.0)

当在官方Oracle JDK 1.7.0下运行时,使用Microsoft JDBC-Driver version 3.0从SQLServer2008中检索DATE类型的列时,我有奇怪的效果.主机操作系统是Windows Server 2003.

相对于实际存储在列中的值,过去检索“所有日期”列为两天.

我做了一个最小的代码示例,测试出来(测试表和数据):

CREATE TABLE Java7DateTest (
  dateColumn DATE
);
INSERT INTO Java7DateTest VALUES('2011-10-10');

码:

public class Java7SQLDateTest {

    public static void main(final String[] argv) {
        try {
            Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
            Connection connection = DriverManager.getConnection(
                    "jdbc:sqlserver://192.168.0.1:1433;databaseName=dbNameHere",
                    "user", "password");
            PreparedStatement statement = connection.prepareStatement("SELECT * FROM Java7DateTest");
            ResultSet resultSet = statement.executeQuery();
            while (resultSet.next()) {
                final java.sql.Date date = resultSet.getDate("dateColumn");
                final String str = resultSet.getString("dateColumn");
                System.out.println(date + " (raw: " + str + ")");
            }
            resultSet.close();
            statement.close();
            connection.close();
        } catch (final Throwable t) {
            throw new RuntimeException(t.getMessage(), t);
        }
    }

}

在上述配置打印上运行此代码:“2011-10-08(raw:2011-10-08)”.
在JRE 1.6.0_27下打印:“2011-10-10(raw:2011-10-10)”

我找不到任何似乎与我的谷歌问题有关的东西,所以我假设它是愚蠢的我忽略了,或者没有人使用Java7.

有人可以确认这个问题吗?如果我还想使用Java7,我的替代品是什么?

编辑:即使使用-Xint运行时也会发生问题,因此它不是由Hotspot错误引起的.

Edit2:旧版驱动程序(Microsoft 1.28)与JDK1.7.0正常工作(我们在两年前才使用该驱动程序,我认为).
这个例子,jTDS也可以很好地工作.我正在考虑切换到jTDS,但我不愿意这么做,因为我对于我们生产环境的影响可能并不是最明智的.理想情况下,它应该只是工作,但是当我将开发框转换到Java7时我相信.
在生产环境中有一个很胖的数据库,太大,无法创建一个副本,用于测试(或者我们的服务器有这么少的磁盘).所以设置一个应用程序的测试环境并不是很明显的,所以我不得不针对这个数据库进行缩小.

编辑3:jTDS有自己的一组捕捉.我发现一个行为差异打破了我们的一个应用程序. ResultSet.getObject()根据驱动程序(Short vs Integer)返回SmallInt列的不同对象类型. jTDS也不实现JDBC4连接接口,不支持Connect.isValid().

Edit4:上周我发现MSSQL-JDBC 3.0在更新到JDK1.6.0_29之后拒绝连接到任何数据库.那么jTDS就是…我们昨天切换了生产服务器(我把这些应用程序依赖于驱动程序的特性来修复),到目前为止我们没有任何问题.

最佳答案
我不太了解你的答案.但是,我已经按照你的描述重新创建了你的情况.与jdbc驱动程序v3.101和v3.202以及v4.ctp3在jdk1.7下运行时相同.但是,MS的v2驱动程序可以在jdk1.6和jdk1.7下给出您的预期答案.如果您需要快速修复,并且可以移动到较旧的jdbc驱动程序,这可能适用于您.

其他想法是关于MS jdbc驱动程序如何处理SQL Server和jvm之间的Date对象的转换.由于日期的存储没有时区,驱动程序对Date对象的解释基于运行jdbc驱动程序的计算机的默认时区.例如,如果您存储“2011-10-11 12:00”的小日期,并从默认时区设置为GMT-7的机器检索该日期,则Date对象的UTC时间将为“2011-10 -11 19:00′.可能是jdk1.7中有一些变化会影响驱动程序中的这个转换过程,导致一个野性的偏移.您可以尝试使用ResultSet.getDate(列,日历)方法查看具有特定时区的日历是否具有您想要的结果,或者帮助您了解为什么在转换中看到奇怪的偏移量.

转载注明原文:过去2天内以Java 1.7.0运行的SQL Server中的日期列(MSSQL-JDBC 3.0) - 代码日志