[英]How to retrieve the date from the database in a proper way using Java?
我正在嘗試從我的數據庫中檢索日期時間值,並且我已將 upload_date_time 聲明為 Instant,這就是該值在數據庫中的存儲方式。
但是,當我嘗試從數據庫中檢索值時,它給了我“2022-03-01T14:00:00Z”。
上傳訂單表
@NotNull
@Column(name = "upload_date_time", nullable = false)
private Instant uploadDateTime;
public Instant getUploadDateTime() {
return uploadDateTime;
}
public UploadOrder uploadDateTime(Instant uploadDateTime) {
this.uploadDateTime= uploadDateTime;
return this;
}
public void setUploadDateTime(Instant uploadDateTime) {
this.uploadDateTime= uploadDateTime;
}
服務
public PrePickOrderOverPickEmailDTO generateOverPickEmails() {
log.debug("Request to retrieve Upload data : {}");
List<UploadOrder> uploadOrders = uploadPickRepository.findAllByEmailSent(false);
String data = "";
for (UploadOrder order : uploadOrders) {
data = data +
"Upload Date: " + order.getUploadDateTime() +"\n" +
// do others
}
}
很想知道我在這里做錯了什么。 任何幫助都會很棒。 謝謝
由於您評論說您的數據庫時區是 UTC+10:00,那么您所看到的是正確的。
2022-03-02T00:00+10:00
與2022-03-01T14:00:00Z
是同一日期,Z 是 UTC(+0),所以它們都代表相同的日期值,只是用不同的時區表示。
您可以通過以下方式驗證這一點:
jshell> java.time.OffsetDateTime.parse("2022-03-02T00:00+10:00").toInstant()
$4 ==> 2022-03-01T14:00:00Z
要將 UTC 即時本地化到不同的區域,您可以使用Instant::atZone()
或Instant::atOffset()
。
Instant
是一個時刻,沒有指定任何時區。 您實際存儲的Instant
是 UTC 時間 3 月 1 日下午 2 點,與 AEST 時間 3 月 2 日午夜相同。
當您通過 SQL 客戶端查看此值時,SQL 客戶端會將其轉換為您的本地時間,因此您看到的是 3 月 2 日午夜。
當您使用 Java 程序檢索它時,您在顯示它時沒有指定時區或時間偏移量。 當您對Instant
執行此操作時,您會在 UTC 中看到它。
您真正想要做的是在顯示之前將Instant
轉換為LocalDateTime
- 這樣,您就可以在 AEST 或您當地的時區中看到它。 LocalDateTime
class 有一個名為ofInstant
的static
方法,它將執行此操作。 您需要為您的時區傳遞ZoneId
,就像這樣。
LocalDateTime timeInBrisbane = LocalDateTime.ofInstant(uploadDateTime, ZoneId.of("Australia/Brisbane"));
甚至像這樣,獲取系統默認時區。
LocalDateTime timeInDefaultZone = LocalDateTime.ofInstant(uploadDateTime, ZoneId.systemDefault());
您問題上的標簽表明您正在使用Microsoft SQL Server作為您的數據庫引擎。
根據文檔,您應該將列定義為數據類型datetimeoffset
。 該類型類似於存儲時刻的 SQL 標准類型TIMESTAMP WITH TIME ZONE
。
不要使用類型smalldatetime
、 datetime
或datetime2
。 這些缺少時區或與 UTC 的偏移量的上下文。 所以這些不能代表一個時刻,時間線上的一個特定點。
鑒於您的代碼片段使用名稱uploadDateTime
,您的業務邏輯需要跟蹤片刻。 所以你的表列必須是datetimeoffset
類型。
你的第一句話說:
我正在嘗試檢索日期時間值
如果您的意思是 Microsoft SQL Server 中的datetime
時間類型,則您使用的列類型錯誤。 這會給你帶來困惑和麻煩。
OffsetDateTime
雖然您忽略了使用@Column
注釋提及您使用的框架庫。 所以我不能肯定地說,但我可以猜測Instant
在這里使用是錯誤的 Java class 。
JDBC JDBC 4.2 及更高版本的規范要求JDBC 驅動程序支持java.time類。 該規范將 SQL 標准類型TIMESTAMP WITH TIME ZONE
的值映射到 Java class java.time.OffsetDateTime
。 Java class Instant
在 JDBC 中根本沒有映射。
檢索OffsetDateTime
后,您可以根據需要提取Instant
: Instant instant = myOffsetDateTime.toInstant();
.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.