2017-06-06 189 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非常好。 –