tl; dr
ハーフオープン期間を使用するSQLの場合:
"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()
) ;
注意:データベースの列に間違ったタイプを使用していると思います。 モーメントはTIMESTAMP WITH TIME ZONE
でのみ追跡できます 、ない TIMESTAMP WITHOUT TIME ZONE
。詳細については、StackOverflowを検索してください。
一瞬ではない
イェンスによる回答は現在時代遅れです。最近は、最新の java.timeを使用する必要があります。 面倒な古いレガシー日時クラスに取って代わったクラス。
PostgresとSQL標準の両方でのこのデータ型は、UTCからのオフセットまたはタイムゾーンのコンテキストを意図的に欠いています。したがって、このタイプは瞬間を表すことはできず、ではないことに注意してください。 タイムライン上のポイント。
いいえ、データ型が間違っています。 java.sql.Timestamp
は、レガシーであり、設計にひどい欠陥があることに加えて、 クラスは、タイムライン上の特定のポイントである瞬間を表します。したがって、これはタイプTIMESTAMP WITHOUT TIME ZONE
の列との不一致です。 。
LocalDateTime
代わりに、LocalDateTime
を使用する必要があります クラス。このクラスは時刻付きの日付を表しますが、オフセットやタイムゾーンの概念はありません。
データベースから値を取得します。
LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;
データベースに値を送信します。
myPreparedStatement.setObject( … , ldt ) ;
一日の始まり
ここに別の不一致があります。日付のみの値を指定していますが、列には時刻付きの日付の値が含まれています。
別の問題:スマートオブジェクトを使用する必要がある場所でダム文字列を使用しています。 JDBC 4.2以降、 java.timeを交換できます。 データベースを持つオブジェクト。 PreparedStatement
を使用する プレースホルダーを使用して、 `set
時刻の問題がある日付を解決するには、1日の始まりを決定する必要があります。 LocalDateTime
を使用 、説明するタイムゾーンの異常はありません。したがって、1日は常に00:00から始まります。それでも、 java.timeに尋ねる習慣を身につける必要があります。 一日の始まりを決定します。
LocalDate startDate = LocalDate.parse( "2014-11-20" ) ;
LocalDate stopDate = LocalDate.parse( "2014-11-21" ) ;
LocalDateTime start = startDate.atStartOfDay() ;
LocalDateTime stop = stopDate.atStartOfDay() ;
プレースホルダーを使用してSQLを記述します。
期間を定義するためのハーフオープンアプローチの習慣を身に付けるために、考え方を変えることをお勧めします。ハーフオープンでは、最初は包括的 エンディングは排他的ですが 。したがって、20日の1日全体について、20日以降の日付を検索し、それまでの日付を検索しますが、は実行しません。 21日を含む。その最初の部分については、「等しいかそれ以降」の短い言い方は「前ではない」なので、!<
を使用します。 。
String sql = "SELECT * FROM tbl WHERE when !< ? AND when < ? ; " ;
そのsql
をフィードします プリペアドステートメントへの文字列。次に、2つのLocalDateTime
を渡します プレースホルダーのオブジェクト。
myPreparedStatement.setObject( 1 , start ) ;
myPreparedStatement.setObject( 2 , stop ) ;