我在Java 8中使用了新的java.time包。我有一箇舊數據庫,它給了我java.util.Date
,我將其轉換爲Instant
。Java 8 java.time:在Instant中添加TemporalUnit與LocalDateTime
我想要做的是添加一段基於另一個數據庫標誌的時間。我可以增加幾天,幾周,幾個月或幾年。我不想關心我所添加的內容,我希望能夠在未來添加更多選項。
我的第一個想法是Instant.plus()
,但這給了我一個UnsupportedTemporalTypeException
值大於一天。即時顯然不支持大單位時間的操作。好吧,無論如何,LocalDateTime
呢。
所以這給了我這個代碼:
private Date adjustDate(Date myDate, TemporalUnit unit){
Instant instant = myDate.toInstant();
LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
dateTime = dateTime.plus(1, unit);
Instant updatedInstant = dateTime.atZone(ZoneId.systemDefault()).toInstant();
return new Date(dueInstant.toEpochMilli());
}
現在,這是使用新的API時我的第一次,所以我會在這裏錯過了一些東西。但似乎笨重,我認爲我必須去:
Date --> Instant --> LocalDateTime --> do stuff--> Instant --> Date.
即使我沒有使用日期部分,我仍然認爲這是一個有點尷尬。所以我的問題是,我是否完全錯誤,做這件事的最好方法是什麼?
編輯:擴大對註釋的討論。
我想我現在有更好的想法瞭解LocalDateTime和Instant如何與java.util.Date和java.sql.Timestamp一起玩。感謝大家。
現在,更實際的考慮。假設用戶向我發送一個來自世界任何地方的任意時間的日期。他們發給我2014-04-16T13:00:00
,我可以解析成LocalDateTime。然後我直接將其轉換爲java.sql.Timestamp並保存在我的數據庫中。
現在,沒有做任何事情,我從我的數據庫中取出java.sql.timestamp,使用timestamp.toLocalDateTime()
轉換爲LocalDateTime
。都好。然後我使用ISO_DATE_TIME格式將此值返回給我的用戶。結果是2014-04-16T09:00:00
。
我認爲這種差異是由於某種類型的隱式轉換爲/從UTC。我認爲我的默認時區可能會被應用到數值(EDT,UTC-4),這可以解釋爲什麼數字關閉了4個小時。
新的問題。本地時間到UTC的隱式轉換在哪裏發生?什麼是更好的方式來保存時區。我不應該直接從當地時間作爲一個字符串(2014-04-16T13:00:00)到LocalDateTime
?我是否應該期待用戶輸入的時區?
你打算在這裏代表什麼價值? 「即時」在邏輯上不知道日曆系統 - 這只是一個時間點 - 所以增加一個月沒有意義。您還應該仔細考慮您是否真的想要使用系統時區 - 您是否希望針對相同的值獲得不同的結果,具體取決於您正在運行的位置? –
@JonSkeet那麼隨意選擇ZoneId會更合適嗎?總是格林威治時間什麼的看起來這可能會帶來一系列的問題。也許問題是我不知道如何表示我的java.util.date。我有一個時間點。如果符合某些條件,我想在未來將這一點改爲一個月(或日,年,無論)。 – jacobhyphenated
使用UTC可能是最佳選擇,但您確實需要考慮您的要求。它甚至意味着將一個時間點(沒有時區或日曆)改變一個月? –