簡體   English   中英

我應該使用java.util.Date還是切換到java.time.LocalDate

[英]Should I use java.util.Date or switch to java.time.LocalDate

編輯:嗯,顯然這是基於意見的,所以讓我試着更准確地改寫它 -

在不需要任何向后兼容性的Java代碼中使用LocalDate,LocalTime等有任何明確的警告或缺點,如果是這樣 - 它們是什么?

我正在尋找像“當前EE庫X和Y無法正確使用LocalDate”或“這個非常有用的模式被LocalTime打破”等等。


(這是原始問題供參考)

在Java 8中,引入了新的時間API,即java.time.LocalDate等,但java.util.Date未標記為已棄用。

我正在編寫一個新項目,它不需要向后兼容。 我應該只使用LocalDate,LocalDateTime等嗎? 使用這個新API是否有任何缺點,而不是舊的java.util.Date?

特別是 - 我將主要使用JDBC。 從我所看到的JDBC很好地處理java.util.Date。 它是否適合LocalDate?

搜索產生了許多網站,告訴他們如何從一種格式轉換為另一種格式,但是如果新代碼使用舊的API,則沒有明確的答案。

謝謝。

盡管名稱,java.util.Date可用於存儲日期和時間(它存儲自紀元以來的UTC毫秒偏移量)

我肯定會使用新的API,因為它具有更強大的功能:

  • 更容易格式化/解析。 API有自己的格式/解析方法
  • API包括加法/減法操作(minusMinutes,plusDays等)

以上都不適用於java.util.Date

Old Date也可以像這樣轉換為LocalDateTime:

Date oldDate = ...
LocalDateTime newDateTime = 
  LocalDateTime.from(Instant.ofEpochMilli(oldDate.getTime()));

我正在添加Ole VV正確答案

JDBC 4.2

特別是 - 我將主要使用JDBC。

JDBC 4.2增加了對與數據庫交換java.time對象的支持。 請參閱PreparedStatement::setObjectResultSet::getObject方法。

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
LocalDate today = LocalDate.now( z ) ;
myPreparedStatement.setObject( … , today ) ;

恢復。

LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;

對於逃避我的原因,JDBC規范並不要求兩個最常用的類支持: InstantZonedDateTime 您的數據庫和JDBC驅動程序可能會也可能不會添加對這些的支持。

如果沒有,您可以輕松轉換。 OffsetDateTime開始,需要JDBC支持。

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;

要通過特定區域(時區)的人使用的掛鍾時間來查看此時刻,請應用ZoneId以獲取ZonedDateTime對象。

ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant() ;

要調整為UTC,請提取Instant 根據定義, Instant始終為UTC。

Instant instant = odt.toInstant() ;

您可以轉換另一種方式,寫入數據庫。

myPreparedStatement.setObject( … , zdt.toOffsetDateTime() ;  // Converting from `ZonedDateTime` to `OffsetDateTime`. Same moment, same point on the timeline, different wall-clock time.

…和:

myPreparedStatement.setObject( … , instant.atOffset( ZoneOffset.UTC ) ) ;  // Converting from `Instant` to `OffsetDateTime`. Same moment, same point on the timeline, and even the same offset. `OffsetDateTime` is a more flexible class with abilities such as (a) applying various offsets and (b) flexible formatting when generating text, while `Instant` is meant to be a more basic building-block class. 

請注意java.time中使用命名約定atfromtowith等。

Java(現代和舊版)和標准SQL中的日期時間類型表。


關於java.time

java.time框架內置於Java 8及更高版本中。 這些類取代了麻煩的舊遺留日期時間類,如java.util.DateCalendarSimpleDateFormat

要了解更多信息,請參閱Oracle教程 並搜索Stack Overflow以獲取許多示例和解釋。 規范是JSR 310

現在處於維護模式Joda-Time項目建議遷移到java.time類。

您可以直接與數據庫交換java.time對象。 使用符合JDBC 4.2或更高版本的JDBC驅動程序 不需要字符串,不需要java.sql.*類。

從哪里獲取java.time類?

ThreeTen-Extra項目使用其他類擴展了java.time。 該項目是未來可能添加到java.time的試驗場。 您可以在這里找到一些有用的類,比如IntervalYearWeekYearQuarter ,和更多

Java 8及更高版本:無后顧之憂

不,如果您使用的是Java 8或更高版本(內置它),那么您就不應該使用java.time這個現代Java日期和時間API。

人們可能會簡單地考慮的唯一問題是你已經排除的那個。

我正在編寫一個新項目,它不需要向后兼容。

即使為了向后兼容,您也可以安全地使用java.time,因為轉換方法是從Java 8構建到舊類中的。

Java 6和7:權衡

如果您使用的是Java 6或7,則需要使用適用於java.time的ThreeTen- Backport,進一步適用於ThreeTenABP中API級別26以下的Android。 如果您只做很少非常簡單的日期和時間工作,並且前向兼容性不是一個問題,您可以考慮外部依賴是否值得。 請注意,您的外部依賴項只是Java 8及更高版本中內置的后端,因此非常堅固,因此在遷移到Java 8或更高版本之前,您只需要它。 此時您可以更改導入,重新測試並取消后退。

你可以想象的負債的例子

當前EE庫X和Y無法與LocalDate一起正常工作

這里有一些例子,JDK中的庫類也是如此。 我的選擇是在我自己的代碼中使用java.time,只在調用之前轉換為尚未接受java.time類型的API。 相反,如果我從API獲得一個過時類的實例,首先將其轉換為其余部分並使用java.time。

使用LocalTime打破了這個非常有用的模式

我知道沒有這種模式。 相反,java.time使用模式不可變對象工廠方法 ,與大多數舊類相反。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM