Подтвердить что ты не робот

Есть ли способ иметь продолжительность Java8 в течение одного года, которая учитывает високосные годы?

Мне нужно количество дней в году, и я хотел использовать Java8 new time api.

Однако я не могу сделать Duration.ofDays(365), потому что он не учитывает високосные годы. И Duration.of(1, ChronoUnit.YEARS) не летает из-за java.time.temporal.UnsupportedTemporalTypeException: Unit must not have an estimated duration

Я просмотрел "Период", но он не кажется полезным для перехода от нескольких дней до нескольких дней.

Я чувствую, что здесь что-то не хватает? Я мог бы написать что-то, чтобы добавить день, если год является високосным годом, но похоже, что я смогу справиться с этим из коробки.

4b9b3361

Ответ 1

В соответствии с ответом в Получение продолжительности с использованием нового API dateTime вы должны использовать

Period p = Period.ofYears(1);

Важно понимать разницу между Duration (точное число наносекунд) и Period (переменная).

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);
boolean isMember = !LocalDate.now().isAfter(membershipEnd);

Ответ 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 поразительно завершены.


Если вы имеете в виду, с 5 января 2004 года по 5 января 2005 года = 366 и с 2 марта 2004 года по 2 марта 2005 года = 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. Но если дата → = март, февраль в следующем году подсчитывается, в противном случае - в феврале этого года.

Помните, что plusYears(1) не изменит ДЕНЬ или МЕСЯЦ.

Также не рассматриваются ни прыжки второго, ни часа/минута 29 февраля.