Java вычисляет дни в году

Есть ли способ в любом родном классе Java рассчитать, сколько дней было/будет в конкретный год? Как и в, был ли "Високосный год" (366 дней) или нормальный год (365 дней)?

Или мне нужно написать его сам?

Я рассчитываю количество дней между двумя датами, например, сколько дней осталось до моего дня рождения. Я хочу принять во внимание 29 февраля Високосного года. Я сделал все, кроме 29-го.

Ответ 1

Стандартный класс GregorianCalendar имеет метод isLeapyear(). Если у вас есть номер года (скажем, 2008), тогда создайте дату, используя конструктор this, а затем проверьте isLeapyear() впоследствии.

Ответ 2

Другой способ сделать это - задать класс Calendar для фактических максимальных дней в данном году:

Calendar cal = Calendar.getInstance();
cal.setTime(new Date());

int numOfDays = cal.getActualMaximum(Calendar.DAY_OF_YEAR);
System.out.println(numOfDays);

Это приведет к возврату 366 в год бисерации 365 для нормального.

Заметьте, я использовал getActualMaximum вместо getMaximum, который всегда будет возвращать 366.

Ответ 3

Для расчетов DateTime я настоятельно рекомендую использовать библиотеку JodaTime. Для чего вам нужно, в частности, это один лайнер:

Days.daysBetween(date1, date2).getDays();

Надеюсь, это поможет.

Ответ 5

Вы можете посмотреть страницу Wikipedia для очень приятного псевдокода:

if year modulo 400 is 0
       then is_leap_year
else if year modulo 100 is 0
       then not_leap_year
else if year modulo 4 is 0
       then is_leap_year
else
       not_leap_year

Я уверен, что вы можете понять, как реализовать эту логику в Java.: -)

Ответ 6

Вы точно можете использовать случай с Джодой и этот конкретный пример.

Ответ 7

TL;DR

Year.of( 2015 )
    .length()

java.time

В Java 8 и более поздних версиях мы имеем пакет java.time. (Tutorial)

length

Класс Year представляет однолетнее значение. Вы можете допросить его длину.

int daysInYear = Year.of( 2015 ).length();

isLeap

Вы также можете спросить, год ли год високосного года или нет.

Boolean isLeapYear = Year.isLeap( 2015 );

В качестве примера, получите количество дней в году, используя Javas тернарный оператор, например:

minVal = (a < b)? a: b;

В нашем случае мы хотим количество дней в году. Это 365 для непиковых лет и 366 для високосного года.

int daysInYear = ( Year.isLeap( 2015 ) ) ? 366 : 365 ;

День из года

Вы можете получить дневной номер даты. Это число от 1 до 365, или 366 в високосный год.

int dayOfYear = LocalDate.now( ZoneId.of( "America/Montreal" ).getDayOfYear() ;

Иду в другое направление, получим дату на день.

Year.now( ZoneId.of( "America/Montreal" ) ).atDay( 159 ) ;

Вы можете определить прошедшие дни, сравнив эти цифры за год с одним годом. Но есть более простой способ; читайте дальше.

Истекшие дни

Используйте ChronoUnit enum для расчета прошедших дней.

LocalDate start = LocalDate.of( 2017 , 2 , 23 ) ;
LocalDate stop = LocalDate.of( 2017 , 3 , 11 ) ;
int daysBetween = ChronoUnit.DAYS.between( start , stop );

Автоматически обрабатывает Leap Year.


О java.time

Структура java.time встроена в Java 8 и более поздних версий. Эти классы вытесняют неприятные старые legacy классы времени, такие как java.util.Date, Calendar и SimpleDateFormat.

Проект Joda-Time, теперь режим обслуживания, советуем перейти к классам java.time.

Чтобы узнать больше, см. Учебник Oracle. И поиск Qaru для многих примеров и объяснений. Спецификация JSR 310.

Где получить классы java.time?

  • Java SE 8, Java SE 9, а затем
    • Встроенный.
    • Часть стандартного Java API с объединенной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функциональных возможностей java.time портирована на Java 6 и 7 в ThreeTen-Backport.
  • Android

Проект ThreeTen-Extra расширяет java.time с помощью дополнительных классов. Этот проект является доказательством возможных будущих дополнений к java.time. Здесь вы можете найти полезные классы, такие как Interval, YearWeek, YearQuarter и больше.

Ответ 8

Вы можете использовать класс TimeUnit. Для ваших конкретных потребностей это должно делать:

public static int daysBetween(Date a, Date b) {
    final long dMs = a.getTime() - b.getTime();
    return TimeUnit.DAYS.convert(dMs, TimeUnit.MILLISECONDS);
}

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

Изменить: Глупый я, волшебство високосного года происходит в Date.getTime(). Во всяком случае, вам не обязательно иметь дело с этим.