Java рассчитывать дни в году - PullRequest
16 голосов
/ 25 января 2011

Есть ли в каком-либо родном классе Java метод для подсчета, сколько дней было / будет в конкретном году? Например, это был високосный год (366 дней) или нормальный год (365 дней)?

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

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

Ответы [ 8 ]

47 голосов
/ 17 сентября 2012

Еще один способ сделать это - спросить у класса 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.

15 голосов
/ 25 января 2011

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

10 голосов
/ 01 сентября 2015

ТЛ; др

Year.of( 2015 )
    .length()

java.time

В Java 8 и более поздних версиях у нас есть java.time пакет . ( Учебник )

length

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

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

isLeap

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

Boolean isLeapYear = Year.isLeap( 2015 );

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

minVal = (a

В нашем случае мы хотим количество дней в году. Это 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 для расчета прошедших дней.

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

Автоматически обрабатывает високосный год .


О java.time

Платформа java.time встроена в Java 8 и более поздние версии. Эти классы заменяют проблемные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar, & SimpleDateFormat.

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

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

Где взять классы java.time?

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

6 голосов
/ 25 января 2011

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

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

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

4 голосов
/ 25 января 2011
3 голосов
/ 25 января 2011

Точный вариант использования лучше всего решить с помощью Joda, и этот конкретный пример .

3 голосов
/ 25 января 2011

Вы можете посмотреть на странице Википедии , чтобы найти очень хороший псевдокод:

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. : -)

1 голос
/ 25 января 2011

Вы можете использовать класс 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().Во всяком случае, вам не нужно с этим справляться.

...