tl;dr
Pro SQL používající Half-Open span-of-time:"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()
) ;
Pozor:Hádám, že pro svůj sloupec v databázi používáte nesprávný typ. Okamžiky lze sledovat pouze pomocí TIMESTAMP WITH TIME ZONE
, ne TIMESTAMP WITHOUT TIME ZONE
. Pro více informací vyhledejte Stack Overflow.
Ani na okamžik
Odpověď od Jense je nyní zastaralá. V současné době byste měli používat moderní java.time třídy, které nahradily staré staré staré staré staré třídy s datem a časem.
Tento datový typ na Postgresu i standardu SQL záměrně postrádá kontext offsetu-od-UTC nebo časového pásma. Takže pozor, tento typ nemůže představovat okamžik, není bod na časové ose.
Ne, špatný datový typ. java.sql.Timestamp
kromě toho, že je starší a má strašné nedostatky v designu třída představuje okamžik, konkrétní bod na časové ose. Jedná se tedy o nesoulad s vaším sloupcem typu TIMESTAMP WITHOUT TIME ZONE
.
LocalDateTime
Místo toho byste měli používat LocalDateTime
třída. Tato třída představuje datum s časem dne, ale postrádá jakýkoli koncept posunu nebo časového pásma.
Chcete-li získat hodnotu z databáze.
LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;
Chcete-li odeslat hodnotu do databáze.
myPreparedStatement.setObject( … , ldt ) ;
Začátek dne
Máte tu další nesoulad. Zadáváte pouze hodnotu data, ale váš sloupec obsahuje hodnoty data s časem dne.
Další problém:Používáte hloupé řetězce tam, kde byste měli používat inteligentní objekty. Od JDBC 4.2 si můžeme vyměňovat java.time objektů s databází. Použijte PreparedStatement
se zástupnými symboly a předávat objekty přes `set
Abychom vyřešili problém data s denní dobou, musíme určit začátek dne. Pomocí LocalDateTime
, nemáme žádné anomálie v časovém pásmu, které bychom museli zohlednit. Den tedy začíná vždy v 00:00. Měli bychom si však zvyknout ptát se java.time k určení začátku dne.
LocalDate startDate = LocalDate.parse( "2014-11-20" ) ;
LocalDate stopDate = LocalDate.parse( "2014-11-21" ) ;
LocalDateTime start = startDate.atStartOfDay() ;
LocalDateTime stop = stopDate.atStartOfDay() ;
Napište vám SQL se zástupnými symboly.
Navrhuji, abyste změnili své myšlení, abyste si zvykli na polootevřený přístup k definování časového rozpětí. V Half-Open je začátek včetně zatímco koncovka je výlučná . Takže pro jediný celý den 20. dne hledejte data rovnající se nebo pozdější než 20. den a dobíhající do, ale ne včetně 21. Pokud jde o první část, kratší způsob, jak říci „rovná se nebo později“, je „ne dříve“, takže používáme !<
.
String sql = "SELECT * FROM tbl WHERE when !< ? AND when < ? ; " ;
Nakrmte tento sql
řetězec k vašemu připravenému výpisu. Poté předejte dva LocalDateTime
objektů pro zástupné symboly.
myPreparedStatement.setObject( 1 , start ) ;
myPreparedStatement.setObject( 2 , stop ) ;