Duration.ofDays生成UnsupportedTemporalTypeException

时间:2015-12-23 17:31:02

标签: java duration java-time

我正在尝试学习新的Date & Time API。除最后一行外,我的代码正在运行:

LocalDate current=LocalDate.now();
System.out.println(current);

LocalDate personaldate=LocalDate.of(2011,Month.AUGUST, 15);
System.out.println(personaldate);

LocalDate afterten=current.plus(Period.ofDays(10));
System.out.println(afterten);

// error occurs here        
System.out.println(afterten.plus(Duration.ofDays(3)));

当我尝试以天为单位添加持续时间时,会产生错误。谁能帮我理解为什么?

错误:

Exception in thread "main" java.time.temporal.UnsupportedTemporalTypeException: Unsupported unit: Seconds                                                                                             
        at java.time.LocalDate.plus(LocalDate.java:1241)                                                                                                                                              
        at java.time.LocalDate.plus(LocalDate.java:137)                                                                                                                                               
        at java.time.Duration.addTo(Duration.java:1070)                                                                                                                                               
        at java.time.LocalDate.plus(LocalDate.java:1143)                                                                                                                                              
        at TestClass.main(TestClass.java:15)    

5 个答案:

答案 0 :(得分:13)

持续时间使用基于时间的值(秒,纳秒)来测量时间量。期间使用基于日期的值(年,月,日)。 这是链接

https://docs.oracle.com/javase/tutorial/datetime/iso/period.html

与JodaTime相同

答案 1 :(得分:8)

虽然接受的答案是完全正确的,但当我到达这个问题时,我正在寻找一个解决我问题的简单方法。

我发现使用Period不允许我计算两个LocalDate对象之间的天数。 (告诉我两者之间有多少年,几个月和几天,是的,但不仅仅是那个天数。)

然而,要获得我所追求的结果就像添加LocalDate方法一样简单" atStartOfDay"我的每个对象。

所以我的错误代码:

long daysUntilExpiry = Duration.between(LocalDate.now(), training.getExpiryDate()).toDays();

只是调整为:

long daysUntilExpiry = Duration.between(LocalDate.now().atStartOfDay(), training.getExpiryDate().atStartOfDay()).toDays();

这样做可以将对象变成LocalDateTime对象,可以与Duration一起使用。因为这两个对象都有一天的开始作为" time"部分,没有区别。

希望这有助于其他人。

答案 2 :(得分:1)

//(year,month,day)

LocalDate beginDate = LocalDate.of(1899,12,31);    
LocalDate today = LocalDate.now();    
ChronoUnit.DAYS.between(beginDate, today)

答案 3 :(得分:0)

如前所述,持续时间始终以秒为基础,而期间则将当天视为概念。 当代码尝试在LocalDate上添加秒数时会引发异常 - 这也是基于日期的。

像这样更改代码会显示差异:在几天内到达时刻时使用LocalDateTime:

If rngTotal.Value2 <> 1 And Not IsError(rngHours) Then
    'code here
End if

答案 4 :(得分:0)

尝试在单元测试中运行以下代码,亲眼看看您的问题的公认答案应该是 ChronoUnit.DAYS.between(),如 Ravi 所述。

LocalDate date1 = LocalDate.of(2020,6,2);
LocalDate date2 = LocalDate.of(2020,7,4);
System.out.printf("ChronoUnit.DAYS = %d%n", ChronoUnit.DAYS.between(date1, date2));
System.out.printf("Period.between = %d%n",Period.between(date1, date2).getDays());

因为输出将如下所示:

ChronoUnit.DAYS = 32
Period.between = 2

Period 将错误地仅返回差异的天数部分(忽略高阶差异,如月份和年份)。

System.out.printf("Duration.between = %d%n",Duration.between(date1, date2).getSeconds());

这将引发异常,因为 LocalDate 没有为秒计算(未定义的小时、分钟和秒)提供足够的信息。 因此,您必须将其转换为 LocalDateTime,例如通过调用 date1.atStartOfDay()。

System.out.printf("Duration.between = %d%n",Duration.between(date1.atStartOfDay(), date2.atStartOfDay()).get(ChronoUnit.DAYS));

这个调用只会抛出 java.time.temporal.UnsupportedTemporalTypeException: Unsupported unit: Days 因为 Duration 类的 get 方法是如何在 Java 中实现的:

@Override
public long get(TemporalUnit unit) {
    if (unit == SECONDS) {
        return seconds;
    } else if (unit == NANOS) {
        return nanos;
    } else {
        throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
    }
}