2017-06-06 188 views
3

我想設置日期 - 實例的小時和分鐘。我有3個解決方案。設置帶日曆或日期時間的日期

我應該服用什麼,爲什麼? :

版本1:

Calendar calendar = Calendar.getInstance(); 
calendar.setTime(date); 
calendar.set(Calendar.MILLISECOND, 0); 
calendar.set(Calendar.SECOND, 0); 
calendar.set(Calendar.MINUTE, 8); 
calendar.set(Calendar.HOUR, 30); 

return calendar.getTime(); 

版本2:

ZonedDateTime i = date.toInstant() 
.atZone(ZoneId.systemDefault()) 
.withHour(8) 
.withMinute(30); 

return Date.from(i.toInstant()); 

版本3:

ZonedDateTime i = date.toInstant() 
.atZone(ZoneId.systemDefault()) 
.withHour(8) 
.withMinute(30); 

return new Date(i.toEpochSecond()); 
+3

它不會幫助你的第一個版本試圖將小時設置爲30,而你的第二個和第三個版本對秒或毫秒不起作用...... –

+6

我會說版本2.它最少使用遺留API 。 – Barend

+0

即使你改正了......你可以去任何方法 – Akshay

回答

7

版本1使用長期過時Calendar類。它的另一個問題是它使用JVM的當前時區設置,而沒有在代碼中明確說明這一點,這是一個可能在未來某個時候給某人帶來不愉快驚喜的特徵。

第2版儘可能利用較新的類,並且明確指出使用JVM的時區設置。好的解決方案。

版本3也具有版本2的優點,但在轉換爲Date之前轉換爲自時代以來的毫秒。在版本2中通過Instant進行的轉換更自然,因此略爲優選。

正如在評論中提到的,寫在問題中的版本2和3沒有擺脫秒和小數秒。簡單的解決方案(因爲你想要這個)是使用truncatedTo()

ZonedDateTime i = date.toInstant() 
      .atZone(ZoneId.systemDefault()) 
      .withHour(8) 
      .withMinute(30) 
      .truncatedTo(ChronoUnit.MINUTES); 

最重要,當然,如果你可以完全避免使用過時也類Date

+1

真棒。我甚至不知道truncatedTo:D –

-2

如果我挑選版本1

ZonedDateTime是新的API我不常用的

+4

這種推理可以阻止* ever *被使用* * * * * * * * * * * * * 'java.util中。應儘可能地避免使用日曆 - 坦率地說,應該像'java.util.Date'一樣。舊的Java日期/時間API是可怕的; java.time非常好。 –