有没有办法让Java8的持续时间为一年,以解释闰年?

2022-09-01 04:33:17

我需要一年中的天数,我想使用Java8的新时间api。

但是,我不能这样做,因为它没有考虑到闰年。并且不会因为Duration.ofDays(365)Duration.of(1, ChronoUnit.YEARS)java.time.temporal.UnsupportedTemporalTypeException: Unit must not have an estimated duration

我研究了时期,但它似乎对从几年到几天没有用。

我觉得我在这里错过了什么?如果年份是闰年,我可以写一些东西来添加一天,但似乎我应该能够开箱即用地处理这个问题。


答案 1

根据使用新的 dateTime API 获取持续时间中的响应,您应该使用

Period p = Period.ofYears(1);

了解(1 天<的确切纳秒数)和(可变> 1 天)之间的区别非常重要。DurationPeriod

Duration例如,不会考虑闰日、夏令时或闰秒,并且适用于少于一天的持续时间,最多几天。

所以你应该使用。Period

因为不同的年份有不同的天数,所以如果要查找一年中的日期数,则需要指定要说明要讨论的年份。

如果需要特定年份的天数,可以使用

Year.of(year).length()

如果您希望日期从现在起一年后,您可以使用

LocalDate.now().plusYears(1)

LocalDate.now().plus(Period.ofYears(1))

如果您需要两个日期之间的天数,可以使用

ChronoUnit.DAYS.between(start, end)

因此,要查找从现在起一年后的日期的天数,您可以使用

LocalDate today = LocalDate.now();
long days = ChronoUnit.DAYS.between(today, today.plusYears(1));

如果您想查看一年的会员资格是否仍然有效,您可以使用

Period membershipLength = Period.ofYears(1);
LocalDate membershipStart = ...;
LocalDate membershipEnd = membershipStart.plus(membershipLength);

LocalDate today = LocalDate.now();
boolean memberShipEnded = today.isAfter(membershipEnd);
boolean membershipValid = !membershipEnded;

答案 2

很明显,您不需要持续时间(=在两个日期之间),而是特定日期的年份长度。

LocalDate dateLeap = LocalDate.of(2004, Month.MARCH, 1);
System.out.println("leap year of " + dateLeap
    + " has days: " + dateLeap.lengthOfYear());

闰年 2004-03-01 有天: 366

Java 8 Date & Time 是惊人的完整。


如果你的意思是,在 2004 年 1 月 5 日至 2005 年 1 月 5 日 = 366 和 2004 年 3 月 2 日至 2005 年 3 月 2 日 = 365

int lengthOfYear(LocalDate date) {
    return date.getMonthValue() <= 2
        ? date.lengthOfYear()               // Count Feb in this year
        : date.plusYears(1).lengthOfYear(); // Count Feb in next year
}

说明:基本上长度是365。但是,如果日期> = 3 月,则计算下一年的 2 月,否则计算今年的 2 月。

注意不会改变日或月。plusYears(1)

此外,既不考虑2月29日的闰秒,也不考虑小时/分钟。


推荐