Я думаю, что вы хотите это:
if (! (paramEnd.before(userDate) || paramStart.after(userEnd))) {
filter.add(param);
}
Да, это просто.Вы можете сказать, что я изменил условие.Вам не нужны статьи, срок действия которых заканчивается до userDate
, а также не нужны статьи, срок действия которых начинается после userEnd
.Все остальные статьи перекрываются с пользовательским интервалом, поэтому они включены.
Тем не менее используемый вами класс Date
давно устарел и имеет ряд проблем с дизайном.И SimpleDateFormat
славится проблемами.Кроме того, Date
, несмотря на свое название, представляет собой не дату, а момент времени.Я рекомендую вам использовать LocalDate
из java.time, современного Java-API даты и времени, для представления даты как внутри вашего Article
класса, так и в коде поиска и фильтрации.В качестве дополнительного бонуса LocalDate
анализирует ваш формат даты yyyy-MM-dd
без какого-либо явного средства форматирования, поскольку этот формат является стандартным (он также известен как ISO 8601).Например:
public class Article {
LocalDate startDateValidity;
LocalDate endDateValidity;
// Note that this constructor accepts string arguments for convenience
public Article(String startValidity, String endValidity) {
this.startDateValidity = LocalDate.parse(startValidity);
this.endDateValidity = LocalDate.parse(endValidity);
}
// getters etc.
}
В filterResult
парсинг dateStart
и dateEnd
в LocalDate
в том же выражении, что и в конструкторе выше.Если dateEnd
отсутствует, установите userEnd
tp LocalDate.MAX
.Ваше if
условие не сильно меняется, когда все даты LocalDate
;перед именами методов стоит is
:
if (! (paramEnd.isBefore(userDate) || paramStart.isAfter(userEnd))) {
filter.add(param);
}
РЕДАКТИРОВАТЬ: давайте проверим это.
Используя даты 6 регистраций из вашего вопроса:
List<Article> list = Arrays.asList(
new Article("2018-09-01", "2018-09-30"),
new Article("2018-10-01", "2018-10-05"),
new Article("2017-12-31", "2018-11-30"),
new Article("2018-12-01", "2019-10-01"),
new Article("2018-12-30", "2018-12-31"),
new Article("2018-11-30", "2018-12-01"));
LocalDate userDate = LocalDate.parse("2018-12-01");
LocalDate userEnd = LocalDate.MAX;
for(Article param : list) {
LocalDate paramStart = param.getStartDateValidity();
LocalDate paramEnd = param.getEndDateValidity();
if (! (paramEnd.isBefore(userDate) || paramStart.isAfter(userEnd))) {
System.out.println("Included " + param);
}
}
Этот фрагмент напечатал следующий вывод:
Included Article [startDateValidity=2018-12-01, endDateValidity=2019-10-01]
Included Article [startDateValidity=2018-12-30, endDateValidity=2018-12-31]
Included Article [startDateValidity=2018-11-30, endDateValidity=2018-12-01]
Вы узнаете даты регистраций № 4, 5 и 6, которые, как вы сказали, вы хотели бытьвставлен в массив фильтров.
Что пошло не так в вашем коде?
У меня две проблемы -> 1º Мой объект всегда защищен в моем массиве.2º Я не знаю, правильна ли моя логика ...
Вы правы, что ваша логика неверна.Давайте посмотрим на ваше if
условие:
if(paramStart.after(userDate)
|| paramEnd.before(userDate) && paramStart.after(userEnd)
|| paramEnd.before(userEnd)) …
&&
имеет более высокий приоритет, чем ||
, поэтому оно интерпретируется так, как будто в скобках paramEnd.before(userDate) && paramStart.after(userEnd)
.Однако эта средняя часть условия реально никогда не будет истинной, но статья будет включена, если первая или последняя часть соответствуют действительности.Только регистрация номер 5 выполняет первую часть условия, потому что after
означает «строго после».Однако все 6 регистраций выполняют последнюю часть, paramEnd.before(userDate) && paramStart.after(userEnd)
.С ||
между частями этого достаточно, чтобы все 6 статей были включены в результат фильтрации.
Ссылки