Java Duration.ofDays生成不受支持的TemporalTypeException

Java Duration.ofDays生成不受支持的TemporalTypeException,java,duration,java-time,Java,Duration,Java Time,我正在努力学习新知识。我的代码正在运行,但最后一行除外: 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.ou

我正在努力学习新知识。我的代码正在运行,但最后一行除外:

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)    

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


与JodaTime中的相同

虽然公认的答案完全正确,但当我提出这个问题时,我正在寻找一个简单的解决方案

我发现使用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一起使用。因为这两个对象都有一天的开始作为“时间”部分,所以没有区别


希望这对其他人有所帮助。

正如前面所暗示的,持续时间总是以秒为基础的,而句号则以一天为概念。 当代码试图在LocalDate上添加秒数时抛出异常,LocalDate也是基于日期的

这样更改代码会显示出区别:在几天内开始处理实例时使用LocalDateTime:

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

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

// error occurred here - but with LocalDateTime is resolved!
System.out.println(afterten.plus(Duration.ofDays(3)));

尝试在单元测试中运行以下代码,并亲自查看问题的公认答案应该是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将错误地只返回差异的天数部分(忽略高阶差异,如月份和年份)

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

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

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

Duration尝试将纳秒添加到LocalDate,这是不正确的。但周期会增加天数。它是关于Period和duration类的实现。编辑您的答案并详细添加。要添加的是,您可以对LocalDateTime对象应用天数的持续时间-它将增加日期的day部分,并且有效,因为它添加了24小时内的秒数(乘以传递给该方法的天数)这就是它在LocalDate上失败的原因,因为LocalDate没有“秒”组件。虽然此代码片段可能是解决方案,但确实有助于提高您的文章质量。请记住,您将在将来回答读者的问题,这些人可能不知道您代码建议的原因。Period#getDays的问题是它只返回差异的“天”部分,因此如果差异为3个月零2天,则返回2。ChronoUnit返回3个月和2天加起来的实际总天数。你说“我发现使用期限不允许我计算天数”是什么意思
Period.between(date1,date2)。days
实际上就是这样做的。@我不确定我在规范中看到过Period的公共可访问属性-也许你使用的Java版本与我不同。getDays()将获取第一次删除所有月份和年份的期间天数。所以对于“离我的大假期还有2年7个月23天”这类逻辑来说非常有用,但对于我想做的事情来说却不是这样!实际上,我认为
Period.getDays
返回完整的天数。我错了。谢谢
System.out.printf("Duration.between = %d%n",Duration.between(date1, date2).getSeconds());
System.out.printf("Duration.between = %d%n",Duration.between(date1.atStartOfDay(), date2.atStartOfDay()).get(ChronoUnit.DAYS));
@Override
public long get(TemporalUnit unit) {
    if (unit == SECONDS) {
        return seconds;
    } else if (unit == NANOS) {
        return nanos;
    } else {
        throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
    }
}