我正在使用Java JDBC将日期写入SQL Server 2008,然后将其读回 回读的日期始终比实际写入的日期提前两天。
我使用预准备语句插入包含Date字段的行。日期值由:
提供java.sql.Date todaysDate = new java.sql.Date(System.currentTimeMillis()) ;
System.out.println(todaysDate.toString()) // -> 2012-07-02
ps.setDate(8, todaysDate);
将日期写入数据库后,如果我运行,SQL服务器会显示正确的日期:
select date from table_name where date!=null // ->2012-07-02
如果我通过JDBC运行相同的查询,则使用
从结果集中检索日期值java.sql.Date sqlDate = rs.getDate("date") ;
sqlDate.toString() // ->2012-06-30
插入的行是表中唯一具有非空日期的行,因此这似乎不是读取错误记录的情况。
我认为这是一个众所周知的问题,但我在谷歌搜索“两天休息”问题时找到的唯一参考资料没有明确的答案。
有什么想法吗?
beeky(生活在过去)答案 0 :(得分:19)
事实证明问题是MS JDBC驱动程序。我尝试了日期类型和日期转换的所有可能组合,但没有任何效果。经过大量的搜索(应该先完成!)我看到an older SO entry上的一条评论暗示问题是来自Microsoft的版本3 JDBC驱动程序。我得到了最新的驱动程序,版本4.something,问题消失了。
感谢所有想要帮助的人。特别感谢Mike花时间发布解决方案。
- = beeky
答案 1 :(得分:4)
对于那些使用maven的人,请将其用于java 8:
{{1}}
正如所指出的,如果您使用的是旧版本,则可能会遇到此问题,并且调试起来并不容易。
答案 2 :(得分:2)
如果您使用的是MSSQL 2015,请使用此Sqljdbc41来解决此问题
<!-- https://mvnrepository.com/artifact/com.microsoft.sqlserver/sqljdbc41 -->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc41</artifactId>
<version>6.0.8112</version>
</dependency>
答案 3 :(得分:1)
我最近遇到过这个问题几次并撕掉我的头发,然后记住如果字段是日期类型,则将字段类型切换为类型datetime可以解决问题。
答案 4 :(得分:1)
答案 5 :(得分:1)
当我们在Microsoft sql中使用日期DataType时,这个问题就出现了。我已修复此问题以将日期更改为日期时间。
答案 6 :(得分:0)
您的问题是时区值(“GMT”)
您需要在JDBC
提取方法中引入此操作,如下所示:
Calendar gmt = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setDate(1, new Date(0)); // I assume this is always GMT
ResultSet rs = stmt.executeQuery();
rs.next();
//This will output 0 as expected
System.out.println(rs.getDate(1, gmt).getTime());
答案 7 :(得分:0)
我有完全相同的问题。一旦我使用java 6运行时环境而不是java 7运行时环境,2天的偏移就消失了。
因此,JDBC版本4.1与JDBC 3驱动程序的向后兼容性之间可能存在差异。
答案 8 :(得分:0)
即使在Java 8中使用sqljdbc4,我也遇到了同样的问题。
一旦我不需要此字段在应用程序中进行任何类型的比较,我通过在我的查询中强制转换字段来解决问题:CAST(dbo.tblPwActividadeParticipanteDetalhe.Data AS VARCHAR(10))
。