tl; dr
Sử dụng JPA 2.2 để được hỗ trợ java.time .
Sử dụng lớp chỉ ngày trong Java để làm việc với các giá trị chỉ ngày trong SQL.
LocalDate // Represent a date-only, without a time-of-day and without a time zone.
.now( // Get today's date…
ZoneId.of( "Africa/Tunis" ) // …as seen in the wall-clock time used by the people of a particular region.
) // Returns a `LocalDate` object.
.plusMonths( 1 ) // Returns another `LocalDate` object, per immutable objects pattern.
java.time
JPA 2.2 hiện hỗ trợ java.time hiện đại các lớp học. Không cần sử dụng Joda-Time nữa.
Không không sử dụng java.sql.Date
. Lớp đó giả vờ để đại diện cho ngày chỉ nhưng thực sự có thời gian trong ngày được đặt thành UTC vì quyết định thiết kế khủng khiếp kế thừa từ java.util.Date
(mặc dù tên đại diện cho một ngày và thời gian trong ngày và độ lệch 0 cho chính UTC). Những lớp kế thừa này là một mớ hỗn độn tồi tệ. Sun, Oracle và cộng đồng JCP đều đã từ bỏ các lớp luận văn nhiều năm trước khi áp dụng JSR 310, và bạn cũng vậy.
LocalDate
LocalDate
lớp đại diện cho giá trị chỉ ngày không có thời gian trong ngày và không có múi giờ
hoặc offset-from-UTC
.
Múi giờ rất quan trọng trong việc xác định ngày. Đối với bất kỳ thời điểm cụ thể nào, ngày thay đổi trên toàn cầu theo khu vực. Ví dụ:vài phút sau nửa đêm ở Paris Pháp là một ngày mới trong khi vẫn là “ngày hôm qua” trong Montréal Québec .
Nếu không có múi giờ nào được chỉ định, JVM sẽ áp dụng hoàn toàn múi giờ mặc định hiện tại của nó. Mặc định đó có thể thay đổi bất kỳ lúc nào trong thời gian chạy (!), vì vậy kết quả của bạn có thể khác nhau. Tốt hơn là chỉ định múi giờ mong muốn / dự kiến của bạn một cách rõ ràng như một đối số. Nếu quan trọng, hãy xác nhận khu vực với người dùng của bạn.
Chỉ định tên múi giờ thích hợp
ở định dạng Continent/Region
, chẳng hạn như America/Montreal
, Africa/Casablanca
hoặc Pacific/Auckland
. Không bao giờ sử dụng từ viết tắt 2-4 chữ cái, chẳng hạn như EST
hoặc IST
vì họ không không múi giờ đúng, không được tiêu chuẩn hóa và thậm chí không phải là duy nhất (!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
Nếu bạn muốn sử dụng múi giờ mặc định hiện tại của JVM, hãy yêu cầu múi giờ đó và chuyển làm đối số. Nếu bị bỏ qua, mã sẽ trở nên mơ hồ khi đọc và chúng tôi không biết chắc chắn liệu bạn có định sử dụng mã mặc định hay không hoặc nếu bạn, giống như rất nhiều lập trình viên, không biết về vấn đề này.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
Hoặc chỉ định một ngày. Bạn có thể đặt tháng bằng một số, với việc đánh số lành mạnh từ 1-12 cho tháng 1 đến tháng 12.
LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ; // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.
Hoặc, tốt hơn, hãy sử dụng Month
các đối tượng enum được xác định trước, một đối tượng cho mỗi tháng trong năm. Mẹo:Sử dụng Month
này các đối tượng trong toàn bộ cơ sở mã của bạn thay vì chỉ là một số nguyên để làm cho mã của bạn tự lập tài liệu hơn, đảm bảo các giá trị hợp lệ và cung cấp loại-an toàn
. Ditto cho Year
& YearMonth
.
LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;
Toán ngày giờ
Rõ ràng bạn muốn bắt đầu với một ngày và lấy một tháng sau làm phạm vi ngày.
LocalDate monthLater = ld.plusMonths( 1 ) ;
JDBC 4.2
Kể từ JDBC 4.2, trình điều khiển JDBC của bạn được yêu cầu hỗ trợ một số khóa java.time các lớp như LocalDate
.
Phạm vi ngày
Lưu ý các liên kết bên dưới cho ThreeTen-Extra . Bạn có thể tìm thấy LocalDateRange
lớp ở đó sẽ hữu ích nếu bạn làm nhiều việc với phạm vi ngày.
Giới thiệu về java.time
java.time
khung công tác được tích hợp vào Java 8 trở lên. Các lớp này thay thế cho kế thừa
cũ rắc rối các lớp date-time chẳng hạn như java.util.Date
, Calendar
& SimpleDateFormat
.
Để tìm hiểu thêm, hãy xem Hướng dẫn Oracle . Và tìm kiếm Stack Overflow để có nhiều ví dụ và giải thích. Đặc điểm kỹ thuật là JSR 310 .
Joda-Time dự án, hiện đang ở chế độ bảo trì , khuyên bạn nên di chuyển sang java.time các lớp học.
Bạn có thể trao đổi java.time các đối tượng trực tiếp với cơ sở dữ liệu của bạn. Sử dụng trình điều khiển JDBC
tuân thủ JDBC 4.2
hoặc sau đó. Không cần chuỗi, không cần java.sql.*
các lớp học.
Lấy các lớp java.time ở đâu?
- Java SE 8
, Java SE 9
, Java SE 10
, Java SE 11
và sau này - Một phần của API Java tiêu chuẩn với một triển khai đóng gói.
- Java 9 bổ sung một số tính năng nhỏ và các bản sửa lỗi.
- Java SE 6
và Java SE 7
- Hầu hết java.time chức năng được chuyển ngược sang Java 6 &7 trong ThreeTen-Backport .
- Android
- Các phiên bản triển khai gói Android mới hơn của java.time lớp học.
- Đối với Android cũ hơn (<26), ThreeTenABP dự án điều chỉnh ThreeTen-Backport (đã đề cập ở trên). Xem Cách sử dụng ThreeTenABP… .
ThreeTen-Extra
dự án mở rộng java.time với các lớp bổ sung. Dự án này là cơ sở chứng minh cho những bổ sung có thể có trong tương lai cho java.time. Bạn có thể tìm thấy một số lớp hữu ích tại đây, chẳng hạn như Interval
, YearWeek
, YearQuarter
và khác
.