Подтвердить что ты не робот

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 для проблемы "двух выходных", не имела однозначного ответа.

Есть идеи?

Бики (живущий в прошлом)

4b9b3361

Ответ 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)).