tl;dr
Per SQL che utilizza l'intervallo di tempo 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()
) ;
Attenzione:suppongo che tu stia usando il tipo sbagliato per la tua colonna nel tuo database. I momenti possono essere monitorati solo con TIMESTAMP WITH TIME ZONE
, non TIMESTAMP WITHOUT TIME ZONE
. Cerca Stack Overflow per ulteriori informazioni.
Neanche un momento
La risposta di Jens è ormai superata. Al giorno d'oggi dovresti usare il moderno java.time classi che hanno soppiantato le fastidiose vecchie classi data-ora.
Questo tipo di dati sia su Postgres che sullo standard SQL manca di proposito del contesto di un offset da UTC o di un fuso orario. Quindi, attenzione, questo tipo non può rappresentare un momento, non un punto sulla sequenza temporale.
No, tipo di dati errato. Oltre ad essere legacy e ad essere terribilmente imperfetto nel design, java.sql.Timestamp
la classe rappresenta un momento, un punto specifico sulla timeline. Quindi questa è una mancata corrispondenza con la tua colonna di tipo TIMESTAMP WITHOUT TIME ZONE
.
LocalDateTime
Dovresti invece usare LocalDateTime
classe. Questa classe rappresenta una data con un'ora del giorno ma non ha alcun concetto di offset o fuso orario.
Per recuperare un valore dal database.
LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;
Per inviare un valore al database.
myPreparedStatement.setObject( … , ldt ) ;
Inizio della giornata
Hai un'altra discrepanza qui. Stai fornendo un valore di sola data ma la tua colonna contiene valori di data con ora del giorno.
Un altro problema:stai usando stringhe stupide in cui dovresti usare oggetti intelligenti. A partire da JDBC 4.2 possiamo scambiare java.time oggetti con il database. Usa un PreparedStatement
con segnaposto e passare gli oggetti tramite il `set
Per risolvere il problema della data con l'ora, dobbiamo determinare l'inizio della giornata. Con LocalDateTime
, non abbiamo anomalie di fuso orario di cui tenere conto. Quindi la giornata inizia sempre alle 00:00. Tuttavia, dovremmo prendere l'abitudine di chiedere a java.time per determinare l'inizio della giornata.
LocalDate startDate = LocalDate.parse( "2014-11-20" ) ;
LocalDate stopDate = LocalDate.parse( "2014-11-21" ) ;
LocalDateTime start = startDate.atStartOfDay() ;
LocalDateTime stop = stopDate.atStartOfDay() ;
Scrivi il tuo SQL con i segnaposto.
Ti suggerisco di cambiare il tuo modo di pensare per prendere l'abitudine dell'approccio Half-Open per definire l'intervallo di tempo. In Half-Open, l'inizio è inclusivo mentre il finale è esclusivo . Quindi per il singolo giorno intero del 20, cerca date uguali o successive al 20 e fino a, ma non compreso, il 21. Per quanto riguarda quella prima parte, un modo più breve per dire "uguale a o successivo" è "non prima", quindi usiamo !<
.
String sql = "SELECT * FROM tbl WHERE when !< ? AND when < ? ; " ;
Dai da mangiare a quel sql
stringa alla tua dichiarazione preparata. Quindi passa i due LocalDateTime
oggetti per i segnaposto.
myPreparedStatement.setObject( 1 , start ) ;
myPreparedStatement.setObject( 2 , stop ) ;