2012-07-02 18 views
19

Estoy usando Java JDBC para escribir una fecha en el servidor sql 2008 y luego volver a leerla.
La fecha leída es consistentemente dos días antes que la fecha tal como está escrita.fechas consistentemente dos días de descanso

Estoy insertando la fila que contiene el campo Fecha con una declaración preparada. El valor de fecha es proporcionada por:

java.sql.Date todaysDate = new java.sql.Date(System.currentTimeMillis()) ; 
System.out.println(todaysDate.toString()) -> 2012-07-02 
ps.setDate(8, todaysDate); 

Después de escribir la fecha en la db, sql server me muestra la fecha correcta si funciono:

select date from table_name where date!=null ->2012-07-02 

Si me quedo la misma consulta a través de JDBC a continuación, recuperar el valor de fecha del conjunto de resultados utilizando

java.sql.Date sqlDate = rs.getDate("date") ; 
sqlDate.toString() ->2012-06-30 

la fila insertada es la única fila de la tabla con una fecha que no sea nulo por lo que este no parece ser un caso de leer el registro incorrecto.

Pensé que este sería un problema bien conocido, pero la única referencia que pude encontrar en una búsqueda de Google para un problema de "dos días de descanso" no tuvo una respuesta definitiva.

¿Alguna idea?

beeky (vivir en el pasado)

+0

Si usa preparedStatement, no convierta desde o hacia String. Pase un objeto de fecha (o marca de tiempo) a setDate. –

+0

¿Cuáles son las zonas horarias tanto del servidor como del cliente? –

+0

¿Estás seguro de que esto no tiene nada que ver con MM-DD-YYYY frente a DD-MM-YYYY? Si sus fechas van desde y hacia cadenas, pueden ser reinterpretadas por configuraciones locales de formas interesantes e inesperadas (en el tiempo de ejecución del cliente y en las bibliotecas de bases de datos y en el código de la base de datos). –

Respuesta

16

defectuoso del controlador JDBC

Resulta que el problema era el controlador de MS JDBC. Probé todas las combinaciones posibles de tipos de fecha y conversiones de fecha y nada funcionó. Después de una gran cantidad de búsquedas (¡debería haber hecho eso primero!) Vi un comentario sobre una entrada SO más antigua que implicaba que el problema era el controlador jdbc versión 3 de Microsoft. Recibí el controlador más reciente, la versión 4.algo, y el problema desapareció.

Gracias a todos los que intentaron ayudar. Gracias especiales a Mike por tomarse el tiempo para publicar una solución. - = beeky

+0

Es interesante, pero tuve el mismo problema con el frotador JSBC 4 de Microsft, JTDS funciona correctamente – D0dger

0

Su problema es valores de zona horaria ("GMT").
Usted necesidad de introducir esta manipulación en el método de ir a buscar JDBC de la siguiente manera:

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()); 
+0

¿Cómo causaría TZ una diferencia de dos días? Puedo ver un día cerca de la línea de fecha internacional, ¿pero dos? –

+0

Mike, ¿fue su ejemplo la respuesta a mi pregunta o una demostración de cómo ver la compensación de la zona horaria? – user903724

+0

¿Has probado esto y no funcionó? – GingerHead

0

Tenía exactamente el mismo problema. La compensación de 2 días desapareció tan pronto como utilicé el entorno de tiempo de ejecución java 6 en lugar de un entorno de tiempo de ejecución java 7.

Es posible que también haya una diferencia entre la compatibilidad con versiones anteriores de la versión 4.1 de JDBC con los controladores JDBC 3.

1

Me he topado con este problema un par de veces recientemente y me arranqué el cabello antes de recordar que si el campo tiene fecha de tipo esto sucede, cambiar el tipo de campo a tipo datetime resuelve el problema.

0

como lo que dijo user903724, cambie a la versión 4 que sería corregida, pero en mi caso, cuando estoy usando sqljdbc4-3.0.jar, este problema aún se reproduce, pero lo cambio a sqljdbc42.jar, este problema arreglado Espero que mi experiencia sea útil. descarga de sqljdbc42.jar

0

Tuve el mismo problema exacto incluso usando sqljdbc4 con Java 8.

Una vez que no necesito este campo para hacer ningún tipo de comparación en la aplicación, he resuelto el problema lanzando el campo en mi consulta de esta manera: CAST(dbo.tblPwActividadeParticipanteDetalhe.Data AS VARCHAR(10)).

2

Para aquellos que están usando Maven, utilizar esto para java 8:

<dependency> 
    <groupId>com.microsoft.sqlserver</groupId> 
    <artifactId>mssql-jdbc</artifactId> 
    <version>6.2.1.jre8</version> 
</dependency> 

Como se señaló, si utiliza una versión antigua, es posible que se enfrentan a este problema, y ​​no es fácil de depurar .

+0

Como un hecho menor (número de versión del controlador) mejorar una Respuesta preexistente, parece que esto debería haberse publicado como un comentario o como una edición de otra respuesta. –

Cuestiones relacionadas