tl; dr
String sql = "SELECT CURRENT_TIMESTAMP ;
…
OffsetDateTime odt = myResultSet.getObject( 1 , OffsetDateTime.class ) ;
Tránh phụ thuộc vào hệ điều hành máy chủ hoặc JVM cho múi giờ mặc định
Tôi khuyên bạn nên viết tất cả mã của mình để nêu rõ ràng múi giờ mong muốn / dự kiến. Bạn không cần phụ thuộc vào múi giờ mặc định hiện tại của JVM. Và lưu ý rằng múi giờ mặc định hiện tại của JVM có thể thay đổi bất kỳ lúc nào trong thời gian chạy, với bất kỳ mã nào trong bất kỳ chuỗi nào của bất kỳ cuộc gọi ứng dụng nàoTimeZone.setDefault
. Một cuộc gọi như vậy sẽ ảnh hưởng đến tất cả các ứng dụng trong JVM đó ngay lập tức.
java.time
Một số Câu trả lời khác đúng, nhưng hiện đã lỗi thời. Các lớp date-time khủng khiếp đi kèm với các phiên bản Java đầu tiên là thiếu sót, được viết bởi những người không hiểu sự phức tạp và tinh tế của việc xử lý date-time.
Các lớp ngày-giờ kế thừa đã được thay thế bằng các lớp java.time được định nghĩa trong JSR 310.
Để biểu thị một múi giờ, hãy sử dụng ZoneId
. Để biểu diễn một offset-from-UTC, hãy sử dụng ZoneOffset
. Độ lệch chỉ là một số giờ-phút-giây phía trước hoặc phía sau kinh tuyến gốc. Múi giờ nhiều hơn. Múi giờ là lịch sử của những thay đổi trong quá khứ, hiện tại và tương lai đối với khoảng thời gian được sử dụng bởi người dân của một khu vực cụ thể.
Tôi cần bắt buộc thực hiện các thao tác liên quan đến GMT / UTC bất kỳ lúc nào
Để có khoảng chênh lệch 0 giờ-phút-giây, hãy sử dụng hằng số ZoneOffset.UTC
.
Instant
Để ghi lại khoảnh khắc hiện tại theo giờ UTC, hãy sử dụng dấu Instant
. Lớp này đại diện cho một thời điểm trong UTC, luôn luôn ở UTC theo định nghĩa.
Instant instant = Instant.now() ; // Capture current moment in UTC.
ZonedDateTime
Để xem cùng thời điểm đó thông qua thời gian trên đồng hồ treo tường được người dân ở một khu vực cụ thể sử dụng, hãy điều chỉnh thành múi giờ. Cùng một thời điểm, cùng một điểm trên dòng thời gian, thời gian trên đồng hồ treo tường khác nhau.
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
Cơ sở dữ liệu
Bạn đề cập đến một cơ sở dữ liệu.
Để truy xuất một thời điểm từ cơ sở dữ liệu, cột của bạn phải có kiểu dữ liệu giống với chuẩn SQL TIMESTAMP WITH TIME ZONE
. Lấy một đối tượng chứ không phải một chuỗi. Trong JDBC 4.2 trở lên, chúng ta có thể trao đổi các đối tượng java.time với cơ sở dữ liệu. Các OffsetDateTime
theo yêu cầu của JDBC, trong khi Instant
& ZonedDateTime
là không bắt buộc.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Trong hầu hết các cơ sở dữ liệu và trình điều khiển, tôi đoán rằng bạn sẽ có được khoảnh khắc như đã thấy ở UTC. Nhưng nếu không, bạn có thể điều chỉnh theo một trong hai cách:
- Trích xuất một
Instant
: odt.toInstant()
- Điều chỉnh từ độ lệch đã cho thành độ lệch bằng 0: OffsetDateTime odtUtc = odt.withOffsetSameInstant (ZoneOffset.UTC); '.
Giới thiệu về java.time
Các java.time khung được xây dựng vào Java 8 và sau đó. Những lớp học thay thế cái cũ phiền hà di sản lớp học ngày thời gian 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 .
Các Joda thời gian dự án, bây giờ trong chế độ bảo trì , khuyên chuyển đổi sang các java.time lớp.
Bạn có thể trao đổi các đối tượng java.time trực tiếp với cơ sở dữ liệu của mình. Sử dụng trình điều khiển JDBC tương thích với JDBC 4.2 trở lên. Không cần chuỗi, không cần java.sql.*
lớp.
Lấy các lớp java.time ở đâu?