2017-02-03 64 views
1

如何在Java中以可靠的方式比較日期和之後的持續時間? 我面臨的問題是:當我創建java.util.Date的新實例,它的toString()方法返回一個值,包括周和時區的日:從數據庫加載後的Java日期toString以不同的格式加載

Fri Feb 03 10:15:31 CET 2017 

當我堅持這個日期(編輯:Date對象)數據庫表,並加載它放回一個實體的toString方法返回一個不同的格式,這取決於數據庫類型:

In case of MySQL date: 2017-02-03 
In case of MySQL datetime: 2017-02-03 10:24:34.0 

我並不總是有因爲訪問格式化toString方法可能會被我的應用程序中的另一個toString方法隱式調用。

這些問題出現對我來說:

  1. 如何Date對象知道要選擇哪一種格式使用 的toString什麼時候?
  2. 我該如何控制新的Date對象,它應該 僅代表一個日期(即沒有時間分數的一天)呢?
  3. 什麼是最佳做法來比較 數據庫加載之前和之後的對象之間的單元測試中持久對象的日期?

回答

2

使用對象,而不是字符串

不要使用字符串從數據庫數據傳遞到/。使用對象。這是JDBC的目的,用於將數據庫的數據類型轉換爲Java的數據類型(類)。

使用java.time,而不是傳統的類

,因爲他們是出了名麻煩的,混亂的,和有缺陷,不要使用舊日期,時間類,如java.util.Date。現在遺留下來,代之以java.time類。

Date對象在使用toString時如何知道選擇哪種格式?

toString使用的格式是硬編碼的,未選中。你總是從該方法獲得相同的格式。格式選擇不佳,而現代圖書館和協議使用標準的ISO 8601格式。

java.time.Date中很多糟糕的設計選擇之一是toString方法將JVM的當前默認時區應用於實際爲UTC的值的行爲。這產生了實際上並不存在的時區幻覺。

更好地避免這些字符串。在Java和數據庫之間傳遞和獲取對象而不是字符串。請致電PreparedStatement::setObjectResultSet::getObject方法與LocalDateInstant和其他此類java.time對象一起使用。

LocalDate ld = myResultSet.getObject(…); 

如果JDBC driver尚不符合JDBC 4.2,並不能直接處理Java。時間對象,使用java.sql類型簡要回顧一下。通過調用添加到舊類的新方法立即將這些java.sql對象轉換爲java.time對象。

java.sql.Date myJavaSqlDate = myResultSet.getDate(…); 
java.time.LocalDate ld = myJavaSqlDate.toLocalDate(); 

如何控制新的Date對象,它應該只佔一個日期(即,沒有時間部分日)擺在首位?

LocalDate類用於沒有時間和時區的僅限日期的值。這映射到等效的SQL標準DATE類型。您應該使用僅限日期的類型來定義數據庫中的列。

什麼是最佳做法來比較從數據庫中加載它之前和之後的對象之間的單元測試中持久對象的日期?

LocalDate類提供的方法進行比較,如compareToisAfterisBeforeisEqual。其他類是相似的。

這已全部覆蓋了許多次Stack Exchange。請搜索類名稱,例如LocalDateInstant,OffsetDateTime,ZonedDateTime,ZoneIdjava.sql.Timestamp

+0

我不使用字符串來保存日期,我堅持Date對象。我編輯了我的帖子,使其更清晰。在不同的地方使用toString方法,比如在你的IDE中編輯時間和結果對我來說都是不可思議的。現在我有了更好的理解。並感謝給我關於將JDBC Sql Date轉換爲Java 8 LocalDate的提示。看起來我的老司機不支持它。目前的一個,我會用它! – Wombat