tl;dr
Untuk SQL menggunakan 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()
) ;
Hati-hati:Saya menduga Anda menggunakan tipe yang salah untuk kolom Anda di database Anda. Momen hanya dapat dilacak dengan TIMESTAMP WITH TIME ZONE
, tidak TIMESTAMP WITHOUT TIME ZONE
. Cari Stack Overflow untuk info lebih lanjut.
Tidak sebentar
Jawaban oleh Jens sekarang sudah ketinggalan zaman. Saat ini Anda harus menggunakan java.time modern kelas yang menggantikan kelas tanggal-waktu lama yang merepotkan.
Tipe data pada Postgres dan standar SQL ini sengaja tidak memiliki konteks offset-dari-UTC atau zona waktu. Jadi, hati-hati, tipe ini tidak bisa mewakili momen, kan tidak satu titik di garis waktu.
Tidak, tipe data salah. Selain menjadi warisan, dan sangat cacat dalam desain, java.sql.Timestamp
class mewakili momen, titik tertentu pada timeline. Jadi ini tidak cocok dengan kolom Anda dengan tipe TIMESTAMP WITHOUT TIME ZONE
.
LocalDateTime
Anda seharusnya menggunakan LocalDateTime
kelas. Kelas ini mewakili tanggal dengan waktu, tetapi tidak memiliki konsep offset atau zona waktu.
Untuk mengambil nilai dari database.
LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;
Untuk mengirim nilai ke database.
myPreparedStatement.setObject( … , ldt ) ;
Awal hari
Anda memiliki ketidakcocokan lain di sini. Anda memberikan nilai hanya tanggal tetapi kolom Anda menyimpan nilai tanggal-dengan-waktu-hari.
Masalah lain:Anda menggunakan string bodoh di mana Anda harus menggunakan objek pintar. Pada JDBC 4.2 kami dapat menukar java.time objek dengan database. Gunakan PreparedStatement
dengan placeholder, dan meneruskan objek melalui `set
Untuk menyelesaikan tanggal dengan masalah waktu, kita perlu menentukan awal hari. Dengan LocalDateTime
, kami tidak memiliki anomali zona waktu untuk diperhitungkan. Jadi hari selalu dimulai pukul 00:00. Namun demikian, kita harus membiasakan diri menanyakan java.time untuk menentukan awal hari.
LocalDate startDate = LocalDate.parse( "2014-11-20" ) ;
LocalDate stopDate = LocalDate.parse( "2014-11-21" ) ;
LocalDateTime start = startDate.atStartOfDay() ;
LocalDateTime stop = stopDate.atStartOfDay() ;
Tulis Anda SQL dengan placeholder.
Saya sarankan Anda mengubah pemikiran Anda untuk membiasakan pendekatan Setengah Terbuka untuk mendefinisikan rentang waktu. Di Half-Open, awalnya adalah inklusif sedangkan endingnya eksklusif . Jadi untuk satu hari penuh tanggal 20, telusuri tanggal yang sama dengan atau lebih lambat dari tanggal 20, dan berjalan hingga, tetapi tidak termasuk, tanggal 21. Untuk bagian pertama itu, cara yang lebih singkat untuk mengatakan "sama dengan atau lebih baru" adalah "tidak sebelum", jadi kami menggunakan !<
.
String sql = "SELECT * FROM tbl WHERE when !< ? AND when < ? ; " ;
Umpan sql
itu string ke pernyataan yang Anda siapkan. Kemudian berikan dua LocalDateTime
objek untuk placeholder.
myPreparedStatement.setObject( 1 , start ) ;
myPreparedStatement.setObject( 2 , stop ) ;