Answer by Basil Bourque хорош и лаконичен, поэтому его следует использовать, однако он работает только потому, что форматы даты представляют собой простые тексты ISO-8601. Если форматы разные, вам нужно их проанализировать, прежде чем сравнивать. Вот решение, которое анализирует строки, что, конечно, делает логику c более сложной.
Я бы начал с создания вспомогательного класса:
/**
* Class for storing a {@code Temporal} of varying precision,
* {@code Year}, {@code YearMonth}, or {@code LocalDate}.
*/
class DynamicTemporal {
private enum Precision {
YEAR {
@Override
protected int compare(Temporal a, Temporal b) {
return widen(a).compareTo(widen(b));
}
private Year widen(Temporal value) {
return Year.from(value);
}
},
MONTH {
@Override
protected int compare(Temporal a, Temporal b) {
return widen(a).compareTo(widen(b));
}
private YearMonth widen(Temporal value) {
return YearMonth.from(value);
}
},
DAY {
@Override
protected int compare(Temporal a, Temporal b) {
return widen(a).compareTo(widen(b));
}
private LocalDate widen(Temporal value) {
return (LocalDate) value;
}
};
protected abstract int compare(Temporal a, Temporal b);
}
private final Temporal value;
private final Precision precision;
public static DynamicTemporal parse(String text) {
if (text == null || text.equals("NULL"))
return null;
if (text.length() >= 10)
return new DynamicTemporal(LocalDate.parse(text), Precision.DAY);
if (text.length() >= 7)
return new DynamicTemporal(YearMonth.parse(text), Precision.MONTH);
return new DynamicTemporal(Year.parse(text), Precision.YEAR);
}
private DynamicTemporal(Temporal value, Precision precision) {
this.value = value;
this.precision = precision;
}
public int compareTo(DynamicTemporal other) {
Precision effectivePrecision = (this.precision.compareTo(other.precision) <= 0 ? this.precision : other.precision);
return effectivePrecision.compare(this.value, other.value);
}
}
Теперь вы можете легко реализовать isDateInRange()
метод:
private static boolean isDateInRange(String start, String end, String date) {
DynamicTemporal dateTemporal = DynamicTemporal.parse(date);
DynamicTemporal startTemporal = DynamicTemporal.parse(start);
DynamicTemporal endTemporal = DynamicTemporal.parse(end);
if (startTemporal != null && dateTemporal.compareTo(startTemporal) < 0)
return false; // date is before start
if (endTemporal != null && dateTemporal.compareTo(endTemporal) > 0)
return false; // date is after end
return true;
}
Тест (из вопроса)
public static void main(String[] args) {
test("2010-05-15", "2020-05", true, "2010", "2020", "2010-05", "2020-05", "2020-05-22", "2010-05-15", "2010-05-22", "2015-02-25");
test("2010-05-15", "2020-05", false, "2009", "2021", "2010-04", "2020-06", "2010-05-14", "2020-06-01");
test("2010", "2020-05-15", true, "2010", "2020", "2010-05", "2020-05", "2010-05-22", "2010-01-01", "2020-05-15", "2015-02-25");
test("2010", "2020-05-15", false, "2009", "2021", "2020-06", "2020-05-16", "2020-06-01");
test("NULL", "2020-05", true, "2020-05-31", "2020-05", "2020", "2020-05-30", "2020-04", "2019");
test("NULL", "2020-05", false, "2020-06-01", "2020-06", "2021", "2020-06-02", "2020-07", "2022");
test("2010-05-15", "NULL", true, "2010-05-15", "2010-05", "2010", "2010-05-16", "2010-06", "2011");
test("2010-05-15", "NULL", false, "2010-05-14", "2010-04", "2009", "2010-05-13", "2010-03", "2008");
}
private static void test(String start, String end, boolean expected, String... dates) {
for (String date : dates) {
boolean actual = isDateInRange(start, end, date);
System.out.printf("isDateInRange(%-10s, %-10s, %-10s) = %-5s %s%n",
start, end, date, actual, (actual == expected ? "OK" : "FAILED!"));
}
}
Выход
isDateInRange(2010-05-15, 2020-05 , 2010 ) = true OK
isDateInRange(2010-05-15, 2020-05 , 2020 ) = true OK
isDateInRange(2010-05-15, 2020-05 , 2010-05 ) = true OK
isDateInRange(2010-05-15, 2020-05 , 2020-05 ) = true OK
isDateInRange(2010-05-15, 2020-05 , 2020-05-22) = true OK
isDateInRange(2010-05-15, 2020-05 , 2010-05-15) = true OK
isDateInRange(2010-05-15, 2020-05 , 2010-05-22) = true OK
isDateInRange(2010-05-15, 2020-05 , 2015-02-25) = true OK
isDateInRange(2010-05-15, 2020-05 , 2009 ) = false OK
isDateInRange(2010-05-15, 2020-05 , 2021 ) = false OK
isDateInRange(2010-05-15, 2020-05 , 2010-04 ) = false OK
isDateInRange(2010-05-15, 2020-05 , 2020-06 ) = false OK
isDateInRange(2010-05-15, 2020-05 , 2010-05-14) = false OK
isDateInRange(2010-05-15, 2020-05 , 2020-06-01) = false OK
isDateInRange(2010 , 2020-05-15, 2010 ) = true OK
isDateInRange(2010 , 2020-05-15, 2020 ) = true OK
isDateInRange(2010 , 2020-05-15, 2010-05 ) = true OK
isDateInRange(2010 , 2020-05-15, 2020-05 ) = true OK
isDateInRange(2010 , 2020-05-15, 2010-05-22) = true OK
isDateInRange(2010 , 2020-05-15, 2010-01-01) = true OK
isDateInRange(2010 , 2020-05-15, 2020-05-15) = true OK
isDateInRange(2010 , 2020-05-15, 2015-02-25) = true OK
isDateInRange(2010 , 2020-05-15, 2009 ) = false OK
isDateInRange(2010 , 2020-05-15, 2021 ) = false OK
isDateInRange(2010 , 2020-05-15, 2020-06 ) = false OK
isDateInRange(2010 , 2020-05-15, 2020-05-16) = false OK
isDateInRange(2010 , 2020-05-15, 2020-06-01) = false OK
isDateInRange(NULL , 2020-05 , 2020-05-31) = true OK
isDateInRange(NULL , 2020-05 , 2020-05 ) = true OK
isDateInRange(NULL , 2020-05 , 2020 ) = true OK
isDateInRange(NULL , 2020-05 , 2020-05-30) = true OK
isDateInRange(NULL , 2020-05 , 2020-04 ) = true OK
isDateInRange(NULL , 2020-05 , 2019 ) = true OK
isDateInRange(NULL , 2020-05 , 2020-06-01) = false OK
isDateInRange(NULL , 2020-05 , 2020-06 ) = false OK
isDateInRange(NULL , 2020-05 , 2021 ) = false OK
isDateInRange(NULL , 2020-05 , 2020-06-02) = false OK
isDateInRange(NULL , 2020-05 , 2020-07 ) = false OK
isDateInRange(NULL , 2020-05 , 2022 ) = false OK
isDateInRange(2010-05-15, NULL , 2010-05-15) = true OK
isDateInRange(2010-05-15, NULL , 2010-05 ) = true OK
isDateInRange(2010-05-15, NULL , 2010 ) = true OK
isDateInRange(2010-05-15, NULL , 2010-05-16) = true OK
isDateInRange(2010-05-15, NULL , 2010-06 ) = true OK
isDateInRange(2010-05-15, NULL , 2011 ) = true OK
isDateInRange(2010-05-15, NULL , 2010-05-14) = false OK
isDateInRange(2010-05-15, NULL , 2010-04 ) = false OK
isDateInRange(2010-05-15, NULL , 2009 ) = false OK
isDateInRange(2010-05-15, NULL , 2010-05-13) = false OK
isDateInRange(2010-05-15, NULL , 2010-03 ) = false OK
isDateInRange(2010-05-15, NULL , 2008 ) = false OK