Ответ 1
Стандартный класс GregorianCalendar
имеет метод isLeapyear()
. Если у вас есть номер года (скажем, 2008
), тогда создайте дату, используя конструктор this, а затем проверьте isLeapyear()
впоследствии.
Есть ли способ в любом родном классе Java рассчитать, сколько дней было/будет в конкретный год? Как и в, был ли "Високосный год" (366 дней) или нормальный год (365 дней)?
Или мне нужно написать его сам?
Я рассчитываю количество дней между двумя датами, например, сколько дней осталось до моего дня рождения. Я хочу принять во внимание 29 февраля Високосного года. Я сделал все, кроме 29-го.
Стандартный класс GregorianCalendar
имеет метод isLeapyear()
. Если у вас есть номер года (скажем, 2008
), тогда создайте дату, используя конструктор this, а затем проверьте isLeapyear()
впоследствии.
Другой способ сделать это - задать класс 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.
Для расчетов DateTime я настоятельно рекомендую использовать библиотеку JodaTime. Для чего вам нужно, в частности, это один лайнер:
Days.daysBetween(date1, date2).getDays();
Надеюсь, это поможет.
Вы можете посмотреть страницу 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.: -)
Вы точно можете использовать случай с Джодой и этот конкретный пример.
Year.of( 2015 )
.length()
В 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 8 и более поздних версий. Эти классы вытесняют неприятные старые legacy классы времени, такие как java.util.Date
, Calendar
и SimpleDateFormat
.
Проект Joda-Time, теперь режим обслуживания, советуем перейти к классам java.time.
Чтобы узнать больше, см. Учебник Oracle. И поиск Qaru для многих примеров и объяснений. Спецификация JSR 310.
Где получить классы java.time?
Проект ThreeTen-Extra расширяет java.time с помощью дополнительных классов. Этот проект является доказательством возможных будущих дополнений к java.time. Здесь вы можете найти полезные классы, такие как Interval
, YearWeek
, YearQuarter
и больше.
Вы можете использовать класс 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()
. Во всяком случае, вам не обязательно иметь дело с этим.