tl; dr
Đối với SQL sử dụng 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()
) ;
Lưu ý:Tôi đoán bạn đang sử dụng sai loại cho cột trong cơ sở dữ liệu của bạn. Chỉ có thể theo dõi các khoảnh khắc bằng TIMESTAMP WITH TIME ZONE
, không TIMESTAMP WITHOUT TIME ZONE
. Tìm kiếm Tràn ngăn xếp để biết thêm thông tin.
Không lâu nữa
Câu trả lời của Jens hiện đã lỗi thời. Ngày nay, bạn nên sử dụng java.time hiện đại các lớp thay thế các lớp ngày-giờ cũ cũ rắc rối.
Kiểu dữ liệu này trên cả Postgres và tiêu chuẩn SQL cố tình thiếu ngữ cảnh của một offset-from-UTC hoặc một múi giờ. Vì vậy, hãy cẩn thận, loại này không thể đại diện cho một thời điểm, là không một điểm trên dòng thời gian.
Không, kiểu dữ liệu sai. Bên cạnh tính kế thừa và thiếu sót nghiêm trọng trong thiết kế, java.sql.Timestamp
lớp đại diện cho một thời điểm, một điểm cụ thể trên dòng thời gian. Vì vậy, đây là cột không khớp với cột của bạn thuộc loại TIMESTAMP WITHOUT TIME ZONE
.
LocalDateTime
Thay vào đó, bạn nên sử dụng LocalDateTime
lớp. Lớp này đại diện cho một ngày với thời gian trong ngày nhưng thiếu bất kỳ khái niệm nào về độ lệch hoặc múi giờ.
Để lấy một giá trị từ cơ sở dữ liệu.
LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;
Để gửi một giá trị đến cơ sở dữ liệu.
myPreparedStatement.setObject( … , ldt ) ;
Bắt đầu ngày mới
Bạn có một sự không phù hợp khác ở đây. Bạn đang cung cấp giá trị chỉ ngày nhưng cột của bạn giữ các giá trị ngày với thời gian trong ngày.
Một vấn đề khác:Bạn đang sử dụng chuỗi câm, nơi bạn nên sử dụng các đối tượng thông minh. Kể từ JDBC 4.2, chúng tôi có thể trao đổi java.time các đối tượng với cơ sở dữ liệu. Sử dụng PreparedStatement
với trình giữ chỗ và chuyển các đối tượng qua `set
Để giải quyết vấn đề ngày với thời gian trong ngày, chúng ta cần xác định ngày bắt đầu của ngày. Với LocalDateTime
, chúng tôi không có bất thường về múi giờ để giải thích. Vì vậy, một ngày luôn bắt đầu lúc 00:00. Tuy nhiên, chúng ta nên có thói quen hỏi java.time để xác định ngày bắt đầu.
LocalDate startDate = LocalDate.parse( "2014-11-20" ) ;
LocalDate stopDate = LocalDate.parse( "2014-11-21" ) ;
LocalDateTime start = startDate.atStartOfDay() ;
LocalDateTime stop = stopDate.atStartOfDay() ;
Viết cho bạn SQL với trình giữ chỗ.
Tôi khuyên bạn nên thay đổi suy nghĩ của mình để tạo thói quen với cách tiếp cận Nửa mở để xác định khoảng thời gian. Trong Hiệp một mở, phần đầu là bao gồm trong khi phần kết là độc quyền . Vì vậy, trong cả ngày 20, hãy tìm kiếm những ngày bằng hoặc muộn hơn ngày 20 và chạy đến, nhưng không bao gồm, ngày 21. Đối với phần đầu tiên đó, cách ngắn hơn để nói "bằng hoặc sau" là "không phải trước", vì vậy chúng tôi sử dụng !<
.
String sql = "SELECT * FROM tbl WHERE when !< ? AND when < ? ; " ;
Nguồn cấp dữ liệu sql
chuỗi vào câu lệnh đã chuẩn bị của bạn. Sau đó chuyển hai LocalDateTime
đối tượng cho trình giữ chỗ.
myPreparedStatement.setObject( 1 , start ) ;
myPreparedStatement.setObject( 2 , stop ) ;