sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Cuál debería ser el tipo de parámetro en Java cuando es una marca de tiempo sin zona horaria en postgresql?

tl;dr

Para SQL usando un lapso de tiempo Half-Open:
"SELECT * FROM tbl WHERE when !< ? AND when < ? ; "

myPreparedStatement.setObject(       // Use a prepared statement so you can pass smart objects rather than dumb strings.
    1 ,                              // Specify which placeholder is being fulfilled.
    LocalDate                        // Represent a date-only value, without time-of-day and without time zone or offset-from-UTC.
    .parse( "2014-11-20" )           // Parse an input string in standard ISO 8601 format to get a `LocalDate` object.
    .atStartOfDay()                  // Determine the first moment of the day on that date. Returns a `LocalDateTime` object representing a date with time-of-day but lacking any concept of time zone or offset-from-UTC.
) ;
myPreparedStatement.setObject( 
    2 , 
    LocalDate
    .parse( "2014-11-21" )
    .atStartOfDay()
) ;

Cuidado:supongo que está usando el tipo incorrecto para su columna en su base de datos. Los momentos solo se pueden rastrear con TIMESTAMP WITH TIME ZONE , no TIMESTAMP WITHOUT TIME ZONE . Busque Stack Overflow para obtener más información.

Ni un momento

La respuesta de Jens ahora está desactualizada. Hoy en día deberías estar usando el moderno java.time clases que suplantaron a las antiguas y problemáticas clases heredadas de fecha y hora.

Este tipo de datos tanto en Postgres como en el estándar SQL carece deliberadamente del contexto de un desplazamiento desde UTC o una zona horaria. Entonces, cuidado, este tipo no puede representar un momento, es no un punto en la línea de tiempo.

No, tipo de datos incorrecto. Además de ser heredado y tener un diseño terriblemente defectuoso, java.sql.Timestamp clase representa un momento, un punto específico en la línea de tiempo. Así que esto no coincide con su columna de tipo TIMESTAMP WITHOUT TIME ZONE .

LocalDateTime

En su lugar, debería usar LocalDateTime clase. Esta clase representa una fecha con una hora del día pero carece de cualquier concepto de compensación o zona horaria.

Para recuperar un valor de la base de datos.

LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;

Para enviar un valor a la base de datos.

myPreparedStatement.setObject( … , ldt ) ;

Inicio del día

Tienes otro desajuste aquí. Está proporcionando un valor de solo fecha, pero su columna contiene valores de fecha con hora del día.

Otro problema:estás usando cadenas tontas donde deberías estar usando objetos inteligentes. A partir de JDBC 4.2 podemos intercambiar java.time objetos con la base de datos. Usar una PreparedStatement con marcadores de posición y pasar objetos a través de `set

Para resolver el problema de la fecha con la hora del día, necesitamos determinar el comienzo del día. Con LocalDateTime , no tenemos anomalías de zona horaria para tener en cuenta. Entonces el día siempre comienza a las 00:00. Sin embargo, deberíamos acostumbrarnos a preguntar java.time para determinar el comienzo del día.

LocalDate startDate = LocalDate.parse( "2014-11-20" ) ;
LocalDate stopDate = LocalDate.parse( "2014-11-21" ) ;

LocalDateTime start = startDate.atStartOfDay() ;
LocalDateTime stop = stopDate.atStartOfDay() ;

Escribe tu SQL con marcadores de posición.

Le sugiero que cambie su forma de pensar para hacer un hábito del enfoque semiabierto para definir el lapso de tiempo. En Half-Open, el comienzo es inclusivo mientras que el final es exclusivo . Por lo tanto, para todo el día 20, busque fechas iguales o posteriores al 20, y hasta, pero no incluido, el día 21. En cuanto a la primera parte, una forma más corta de decir "igual o posterior" es "no antes", por lo que usamos !< .

String sql = "SELECT * FROM tbl WHERE when !< ? AND when < ? ; " ;

Alimenta ese sql cadena a su declaración preparada. Luego pase los dos LocalDateTime objetos para los marcadores de posición.

myPreparedStatement.setObject( 1 , start ) ;
myPreparedStatement.setObject( 2 , stop ) ;