Java JDBC: даты последовательно два выходных
Я использую Java JDBC, чтобы записать дату на SQL Server 2008 и затем прочитать ее обратно.
Дата, которая считывается обратно, последовательно на два дня раньше даты, которая была фактически написана.
Я вставляю строку, содержащую поле Дата с подготовленным выражением. Значение даты предоставляется:
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
Вставленная строка является единственной строкой в таблице с ненулевой датой, поэтому это не похоже на случай чтения неправильной записи.
Я думал, что это будет хорошо известная проблема, но единственная ссылка, которую я смог найти по поиску в Google для проблемы "двух выходных", не имела однозначного ответа.
Есть идеи?
Бики (живущий в прошлом)
Ответы
Ответ 1
Неисправный драйвер JDBC
Оказывается, проблема была в драйвере MS JDBC. Я перепробовал все возможные комбинации типов дат и преобразований дат, но ничего не получалось. После долгих поисков (я должен был это сделать первым!) Я увидел комментарий к более старой записи SO, которая подразумевала, что проблема заключалась в драйвере JDBC версии 3 от Microsoft. Я получил последний драйвер версии 4. что-то, и проблема ушла.
Спасибо всем, кто пытался помочь. Отдельное спасибо тебе, Майк, за то, что нашел время опубликовать решение.
- = beeky
Ответ 2
Для тех, кто использует maven, используйте это для java 8:
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>6.2.1.jre8</version>
</dependency>
Как указано, если вы используете старую версию, вы можете столкнуться с этой проблемой, и ее нелегко отладить.
Ответ 3
Если вы используете 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>
Ответ 4
Я столкнулся с этой проблемой несколько раз недавно и вырвал свои волосы, прежде чем вспомнить, что если поле имеет тип даты, это происходит, переключая тип поля на тип datetime, решает проблему.
Ответ 5
как то, что сказал user903724, измените на версию 4, которая будет исправлена, но в моем случае, когда я использую sqljdbc4-3.0.jar, эта проблема все еще воспроизводится, но я меняю ее на sqljdbc42.jar, эта проблема получила исправлено. Надеюсь, мой опыт будет полезен.
скачать с sqljdbc42.jar
Ответ 6
Эта проблема возникает, когда мы используем дату DataType в Microsoft SQL. Я исправил это, чтобы изменить дату на дату и время.
Ответ 7
Ваша проблема - значения часового пояса ( "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());
Ответ 8
У меня была точно такая же проблема. 2-дневное смещение ушло, как только я использовал среду исполнения java 6 вместо среды выполнения java 7.
Таким образом, возможно, это также разница между версией JDBC версии 4.1 и совместимостью с драйверами JDBC 3.
Ответ 9
У меня была такая же проблема, даже с использованием sqljdbc4 с Java 8.
Как только мне не понадобится это поле, чтобы сделать какое-либо сравнение в приложении, я решил проблему, выбрав поле в моем запросе следующим образом: CAST(dbo.tblPwActividadeParticipanteDetalhe.Data AS VARCHAR(10))
.