Вопрос-ответ

How do I check if a date is within a certain range?

Как мне проверить, находится ли дата в определенном диапазоне?

У меня есть ряд диапазонов с датами начала и окончания. Я хочу проверить, находится ли дата в этом диапазоне.

Date.before() и Date.after() кажутся немного неудобными в использовании. Что мне действительно нужно, так это что-то вроде этого псевдокода:

boolean isWithinRange(Date testDate) {
return testDate >= startDate && testDate <= endDate;
}

Не уверен, что это актуально, но даты, которые я извлекаю из базы данных, имеют временные метки.

Переведено автоматически
Ответ 1
boolean isWithinRange(Date testDate) {
return !(testDate.before(startDate) || testDate.after(endDate));
}

Мне это не кажется таким уж неудобным. Обратите внимание, что я написал это таким образом, а не

return testDate.after(startDate) && testDate.before(endDate);

таким образом, это сработало бы, даже если TestDate был точно равен одному из конечных значений.

Ответ 2

tl; dr

ZoneId z = ZoneId.of( "America/Montreal" );  // A date only has meaning within a specific time zone. At any given moment, the date varies around the globe by zone.
LocalDate ld =
givenJavaUtilDate.toInstant() // Convert from legacy class `Date` to modern class `Instant` using new methods added to old classes.
.atZone( z ) // Adjust into the time zone in order to determine date.
.toLocalDate(); // Extract date-only value.

LocalDate today = LocalDate.now( z ); // Get today’s date for specific time zone.
LocalDate kwanzaaStart = today.withMonth( Month.DECEMBER ).withDayOfMonth( 26 ); // Kwanzaa starts on Boxing Day, day after Christmas.
LocalDate kwanzaaStop = kwanzaaStart.plusWeeks( 1 ); // Kwanzaa lasts one week.
Boolean isDateInKwanzaaThisYear = (
( ! today.isBefore( kwanzaaStart ) ) // Short way to say "is equal to or is after".
&&
today.isBefore( kwanzaaStop ) // Half-Open span of time, beginning inclusive, ending is *exclusive*.
)

Полуоткрыто

При работе с датой и временем обычно используется "полуоткрытый" подход к определению промежутка времени. Начало является включающим, а окончание - исключающим. Таким образом, неделя, начинающаяся с понедельника, длится до следующего понедельника, но не включает его.

java.time

Java 8 и более поздних версий поставляется со встроенным java.time фреймворком. Заменяет старые проблемные классы, включая java.util.Date/.Calendar и SimpleDateFormat. Вдохновлен успешной библиотекой Joda-Time. Определено в JSR 310. Расширено проектом ThreeTen-Extra.

An Instant - это момент на временной шкале в UTC с разрешением в наносекунду.

Instant

Преобразуйте ваши java.util.Date объекты в Instant objects.

Instant start = myJUDateStart.toInstant();
Instant stop =

При получении java.sql.Timestamp объектов через JDBC из базы данных, преобразуйте в java.time.Instant аналогичным образом. A java.sql.Timestamp уже находится в UTC, поэтому не нужно беспокоиться о часовых поясах.

Instant start = mySqlTimestamp.toInstant() ;
Instant stop =

Получить текущий момент для сравнения.

Instant now = Instant.now();

Сравните, используя методы isBefore, isAfter и equals.

Boolean containsNow = ( ! now.isBefore( start ) ) && ( now.isBefore( stop ) ) ;

LocalDate

Возможно, вы хотите работать только с датой, а не со временем суток.

Класс LocalDate представляет значение только для даты, без указания времени суток и часового пояса.

LocalDate start = LocalDate.of( 2016 , 1 , 1 ) ;
LocalDate stop = LocalDate.of( 2016 , 1 , 23 ) ;

Чтобы получить текущую дату, укажите часовой пояс. В любой данный момент сегодняшняя дата зависит от часового пояса. Например, в Париже новый день наступает раньше, чем в Монреале.

LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );

Мы можем использовать методы isEqual, isBefore и isAfter для сравнения. При работе с датой и временем мы обычно используем полуоткрытый подход, при котором начало промежутка времени является включительным, а окончание - исключительным.

Boolean containsToday = ( ! today.isBefore( start ) ) && ( today.isBefore( stop ) ) ;

Interval

Если вы решили добавить в свой проект библиотеку ThreeTen-Extra, вы могли бы использовать Interval класс для определения промежутка времени. Этот класс предлагает методы для проверки, содержит интервал, примыкает, заключает или перекрывает другие даты / интервалы.

Interval Класс работает с Instant объектами. Instant Класс представляет момент на временной шкале в UTC с разрешением в наносекунды (до девяти (9) цифр десятичной дроби).

Мы можем настроить LocalDate на определенный момент, первое мгновение дня, указав часовой пояс, чтобы получить ZonedDateTime. Оттуда мы можем вернуться к UTC , извлекая Instant.

ZoneId z = ZoneId.of( "America/Montreal" );
Interval interval =
Interval.of(
start.atStartOfDay( z ).toInstant() ,
stop.atStartOfDay( z ).toInstant() );
Instant now = Instant.now();
Boolean containsNow = interval.contains( now );

О java.time

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

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

Чтобы узнать больше, ознакомьтесь с Руководством по Oracle. И найдите в Stack Overflow множество примеров и пояснений. Спецификация - JSR 310.

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


  • Java SE 8 и SE 9 и более поздние версии

  • Встроено.

  • Часть стандартного Java API с комплексной реализацией.

  • Java 9 добавляет некоторые незначительные функции и исправления.

  • Java SE 6 и SE 7

  • Большая часть java.time функциональности перенесена обратно на Java 6 и 7 в ThreeTen-Backport.

  • Android

  • Проект ThreeTenABP адаптирует ThreeTen-Backport (упомянутый выше) специально для Android.

  • Смотрите Как использовать ....

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

Ответ 3

Это правильный способ. Календари работают точно так же. Лучшее, что я мог бы вам предложить (на основе вашего примера), это:

boolean isWithinRange(Date testDate) {
return testDate.getTime() >= startDate.getTime() &&
testDate.getTime() <= endDate.getTime();
}

Date.getTime() возвращает количество миллисекунд, прошедших с 1/1/1970 00:00:00 GMT, и является длительным, поэтому его легко сопоставить.

Ответ 4

Рассмотрите возможность использования Joda Time. Мне нравится эта библиотека, и я бы хотел, чтобы она заменила текущий ужасный беспорядок, который представляют собой существующие классы даты и календаря Java. Обработка даты выполнена правильно.

РЕДАКТИРОВАТЬ: сейчас уже не 2009 год, а Java 8 давно отсутствует. Используйте классы Java 8, встроенные в java.time, которые основаны на времени Joda, как упоминал Бэзил Бурк выше. В этом случае вам понадобится класс Period, и вот руководство Oracle по его использованию.

java date