java.time
Với việc phát hành Java SE 8 vào tháng 3 năm 2014, API ngày giờ kế thừa đã lỗi thời và dễ xảy ra lỗi (java.util
Các loại Ngày-Giờ và kiểu định dạng của chúng, SimpleDateFormat
v.v.) đã được thay thế bởi java.time
, API ngày-giờ hiện đại. bảng sau
mô tả ánh xạ của các kiểu SQL ANSI với java.time
loại:
ANSI SQL | Java SE 8 |
---|---|
NGÀY | Ngày địa phương |
THỜI GIAN | LocalTime |
TIMESTAMP | LocalDateTime |
THỜI GIAN VỚI TIMEZONE | OffsetTime |
ĐẤU TRANH THỜI GIAN VỚI TIMEZONE | OffsetDateTime |
Lưu ý rằng ZonedDateTime
và Instant
không được hỗ trợ bởi bất kỳ trình điều khiển JDBC nào trong khi một số trình điều khiển, ví dụ:PostgreSQL cũng không hỗ trợ OffsetTime
/ TIME [ WITHOUT TIMEZONE ]
. Ngoài ra, hãy lưu ý rằng tất cả OffsetDateTime
các phiên bản sẽ phải ở UTC (có độ lệch 0). Điều này là do chương trình phụ trợ lưu trữ chúng dưới dạng UTC.
Làm thế nào để sử dụng nó trong JDBC?
Dưới đây là mã mẫu để chèn OffsetDateTime
hiện tại trong UTC, thành columnfoo
(thuộc về TIMESTAMP WITH TIMEZONE
loại):
OffsetDateTime odt = Instant.now().atOffset(ZoneOffset.UTC);
PreparedStatement st = conn.prepareStatement("INSERT INTO mytable (columnfoo) VALUES (?)");
st.setObject(1, odt);
st.executeUpdate();
st.close();
Instant
đại diện cho một điểm tức thời trên dòng thời gian và độc lập với múi giờ, tức là nó có độ lệch múi giờ là +00:00
giờ.
Dưới đây là mã mẫu để truy xuất OffsetDateTime
từ columnfoo
:
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM mytable WHERE <some condition>");
while (rs.next()) {
// Assuming the column index of columnfoo is 1
OffsetDateTime odt = rs.getObject(1, OffsetDateTime.class));
System.out.println(odt);
}
rs.close();
st.close();
Chỉ trong trường hợp bạn cần chuyển đổi OffsetDateTime
thành một cái khác có độ lệch khác:
Có một số cách để làm như vậy nhưng tôi chủ yếu sử dụng OffsetDateTime#withOffsetSameInstant
, để chuyển đổi một OffsetDateTime
thành một cái khác có chênh lệch múi giờ khác, ví dụ:
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
// A sample OffsetDateTime in UTC.
OffsetDateTime odt = Instant.now().atOffset(ZoneOffset.UTC);
System.out.println(odt);
OffsetDateTime offsetTimeAtOffset0100 = odt.withOffsetSameInstant(ZoneOffset.of("+02:00"));
System.out.println(offsetTimeAtOffset0100);
// Time at JVM's default timezone offset
ZoneOffset jvmTzOffset = ZonedDateTime.now(ZoneId.systemDefault()).getOffset();
OffsetDateTime offsetTimeAtJvmTzOffset = odt.withOffsetSameInstant(jvmTzOffset);
System.out.println(offsetTimeAtJvmTzOffset);
}
}
Đầu ra:
2021-05-29T13:36:15.258076Z
2021-05-29T15:36:15.258076+02:00
2021-05-29T14:36:15.258076+01:00
Một số điểm liên quan đến đoạn mã được đưa ra ở trên:
-
Z
trong đầu ra là trình chỉ định múi giờ cho độ lệch múi giờ bằng không. Nó là viết tắt của Zulu và chỉ địnhEtc/UTC
múi giờ (có độ lệch múi giờ là+00:00
giờ). - Mã chuyển đổi
odt
thành hai phiên bản củaOffsetDateTime
- mỗi người theo một cách khác nhau. Trường hợp đầu tiên là với độ lệch múi giờ cố định là+02:00
giờ trong khi giờ thứ hai có chênh lệch múi giờ của JVM. Lưu ý rằng độ lệch múi giờ của một địa điểm quan sát DST thay đổi theo thời gian mùa hè / mùa đông. Do đó, nếu một địa điểm quan sát DST, thay vì sử dụng độ lệch múi giờ cố định, ví dụ:+02:00
giờ; chúng ta nên lấy nó từ API. - Múi giờ JVM của tôi là
Europe/London
và hiện tại phần bù của nó là+01:00
giờ.
Tìm hiểu thêm về API ngày-giờ hiện đại from Đường nhỏ:Ngày giờ .