tl;dr
For SQL, der bruger Half-Open tidsrum:"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()
) ;
Pas på:Jeg gætter på, at du bruger den forkerte type til din kolonne i din database. Øjeblikke kan kun spores med TIMESTAMP WITH TIME ZONE
, ikke TIMESTAMP WITHOUT TIME ZONE
. Søg efter Stack Overflow for at få flere oplysninger.
Ikke et øjeblik
Svaret af Jens er nu forældet. I dag bør du bruge den moderne java.time klasser, der fortrængte de besværlige gamle gamle dato-tidsklasser.
Denne datatype på både Postgres og SQL-standarden mangler bevidst konteksten af en offset-fra-UTC eller en tidszone. Så pas på, denne type kan ikke repræsentere et øjeblik, er ikke et punkt på tidslinjen.
Nej, forkert datatype. Udover at være arv og være frygtelig mangelfuld i designet, er java.sql.Timestamp
klasse repræsenterer et øjeblik, et bestemt punkt på tidslinjen. Så dette er en uoverensstemmelse med din kolonne af typen TIMESTAMP WITHOUT TIME ZONE
.
LocalDateTime
Du bør i stedet bruge LocalDateTime
klasse. Denne klasse repræsenterer en dato med et klokkeslæt, men mangler noget begreb om forskydning eller tidszone.
For at hente en værdi fra databasen.
LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;
For at sende en værdi til databasen.
myPreparedStatement.setObject( … , ldt ) ;
Start på dagen
Du har endnu et misforhold her. Du angiver en kun datoværdi, men din kolonne indeholder dato-med-klokkeslæt-værdier.
Et andet problem:Du bruger dumme strenge, hvor du burde bruge smarte objekter. Fra JDBC 4.2 kan vi udveksle java.time objekter med databasen. Brug en PreparedStatement
med pladsholdere, og send objekter via `sættet
For at løse datoen med klokkeslætsproblemet skal vi bestemme starten på dagen. Med LocalDateTime
, vi har ingen tidszone-anomalier at tage højde for. Så dagen starter altid kl 00:00. Ikke desto mindre bør vi vænne os til at spørge java.time for at bestemme starten på dagen.
LocalDate startDate = LocalDate.parse( "2014-11-20" ) ;
LocalDate stopDate = LocalDate.parse( "2014-11-21" ) ;
LocalDateTime start = startDate.atStartOfDay() ;
LocalDateTime stop = stopDate.atStartOfDay() ;
Skriv din SQL med pladsholdere.
Jeg foreslår, at du ændrer din tankegang for at gøre en vane med den halvåbne tilgang til at definere tidsrum. I Half-Open er begyndelsen inklusive mens slutningen er eksklusiv . Så for den enkelte dag i den 20. skal du søge efter datoer, der er lig med eller senere end den 20. og løber op til, men ikke inklusive den 21. Hvad angår den første del, er en kortere måde at sige "lig med eller senere" "ikke før", så vi bruger !<
.
String sql = "SELECT * FROM tbl WHERE when !< ? AND when < ? ; " ;
Feed den sql
streng til din forberedte erklæring. Send derefter de to LocalDateTime
objekter til pladsholderne.
myPreparedStatement.setObject( 1 , start ) ;
myPreparedStatement.setObject( 2 , stop ) ;