tl; dr
myPreparedStatement
.setObject(
… , // Specify which placeholder `?` in your SQL statement.
OffsetDateTime.now( ZoneOffset.UTC ) // Capture the current moment as seen in the wall-clock time of UTC (an offset-from-UTC of zero).
) ;
Tránh các lớp ngày-giờ kế thừa
Bạn đang sử dụng các lớp date-time khủng khiếp đã được thay thế nhiều năm trước bởi java.time các lớp học.
Không bao giờ sử dụng Date
hoặc Timestamp
.
UTC
Ghi lại khoảnh khắc hiện tại, theo giờ UTC. Hầu hết các cơ sở dữ liệu lưu trữ một khoảnh khắc trong UTC. Và nói chung, bạn nên thực hiện hầu hết logic nghiệp vụ của mình, gỡ lỗi, ghi nhật ký, lưu trữ và trao đổi dữ liệu trong UTC.
OffsetDateTime
Thể hiện một khoảnh khắc bằng offset-from-UTC bằng cách sử dụng OffsetDateTime
được đặt tên phù hợp lớp.
Chúng tôi muốn chính UTC, hoặc một khoảng chênh lệch bằng không. Chúng ta có thể sử dụng một hằng số cho điều đó, ZoneOffset.UTC
.
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ) ;
JDBC 4.2
Kể từ JDBC 4.2, chúng tôi có thể trao đổi trực tiếp java.time các đối tượng với cơ sở dữ liệu.
Để lưu khoảnh khắc này vào một cột có kiểu dữ liệu tương tự như TIMESTAMP WITH TIME ZONE
theo tiêu chuẩn SQL :
myPreparedStatement.setObject( … , odt ) ;
Truy xuất:
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
ZonedDateTime
Để trình bày khoảnh khắc đã truy xuất này cho người dùng, bạn có thể muốn điều chỉnh theo múi giờ dự kiến / mong muốn của người dùng.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
Không bao giờ dựa vào múi giờ mặc định
Lưu ý trong đoạn mã ở trên rằng chúng tôi luôn chỉ định khoảng cách hoặc vùng mong muốn / mong đợi.
Nếu bạn không chỉ định, một khoảng chênh lệch hoặc vùng được áp dụng ngầm. Tốt hơn nên chỉ rõ ý định của bạn một cách rõ ràng vì mặc định hiện tại của JVM, cơ sở dữ liệu và hệ điều hành máy chủ lưu trữ đều nằm ngoài tầm tay của bạn với tư cách là một lập trình viên. Điều đó có nghĩa là mã dựa trên mặc định sẽ khác nhau về hành vi trong thời gian chạy.
Java 6 &7
Cùng một người đàn ông, Stephen Colebourne, người dẫn đầu JSR 310 và java.time triển khai, cũng như Joda-Time nổi tiếng dự án, cũng dẫn đầu một dự án khác, ThreeTen-Backport . Hầu hết các java.time chức năng được chuyển ngược lại sang Java 6 &7 trong thư viện này, với API gần như giống hệt nhau.
Vì vậy, hãy thực hiện tất cả công việc của bạn trong các lớp cổng sau. Sau đó, vào giây phút cuối cùng, hãy chuyển đổi thành / từ java.sql.Timestamp
qua DateTimeUtils
lớp.
Các phương pháp chuyển đổi đó chủ yếu sử dụng Instant
các đối tượng. Một Instant
là một thời điểm trong UTC, luôn luôn ở UTC. Bạn có thể điều chỉnh từ OffsetDateTime
của mình sang UTC bằng cách trích xuất một Instant
. Instant
lớp là lớp khối xây dựng cơ bản trong java.time , với OffsetDateDate
linh hoạt hơn, chẳng hạn như các mẫu định dạng thay thế khi tạo một chuỗi. Nhưng cả hai Instant
và OffsetDateTime
đại diện cho một thời điểm, một điểm trên dòng thời gian.
Instant instant = odt.toInstant() ;
java.sql.Timestamp ts = org.threeten.bp.DateTimeUtils.toSqlTimestamp( instant ) ;
Đi theo hướng khác, truy xuất Timestamp
từ cơ sở dữ liệu của bạn, sau đó chuyển đổi ngay lập tức sang Instant
.
java.sql.Timestamp ts = myResultSet.getTimestamp( … ) ;
Instant instant = org.threeten.bp.DateTimeUtils.toInstant( ts ) ;
Giới thiệu về java.time
java.time
khung công tác được xây dựng trong 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
.
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.
Để 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 .
Bạn có thể trao đổi java.time đố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
.