You can make your method receives a java.time.temporal.Temporal
as parameter (or a TemporalAccessor
as suggested by @JodaStephen). This code works for both.
I must admit that I'd prefer to do it like @Lachezar Balev's answer is suggesting, but anyway, here's an alternative.
As a Temporal
can be of any type (LocalDate
, LocalDateTime
, ZonedDateTime
, etc), but you want just LocalDate
and LocalDateTime
, I'm doing the following:
- try to create a
LocalDateTime
first: it requires more fields than a LocalDate
(hour/minute/second), so if it can be created, it's the prefered type
- if it can't be created, I catch the respective exception and try to create a
LocalDate
Another detail is that I also simplified your comparison:
dateFieldToCheck.isAfter(minDate) || dateFieldToCheck.isEqual(minDate)
Is equivalent to:
! dateFieldToCheck.isBefore(minDate)
And a similar simplification was done when comparing with maxDate
:
public boolean check(Temporal dateFieldToCheck, Temporal minDate, Temporal maxDate) {
// try to get as LocalDateTime
try {
LocalDateTime dtCheck = LocalDateTime.from(dateFieldToCheck);
LocalDateTime dtMin = LocalDateTime.from(minDate);
LocalDateTime dtMax = LocalDateTime.from(maxDate);
return (!dtCheck.isBefore(dtMin)) && (!dtCheck.isAfter(dtMax));
} catch (DateTimeException e) {
// exception: one of the Temporal objects above doesn't have all fields required by a LocalDateTime
// trying a LocaDate instead
LocalDate dCheck = LocalDate.from(dateFieldToCheck);
LocalDate dMin = LocalDate.from(minDate);
LocalDate dMax = LocalDate.from(maxDate);
return (!dCheck.isBefore(dMin)) && (!dCheck.isAfter(dMax));
}
}
Now you can call this method with both a LocalDate
and a LocalDateTime
:
check(LocalDate.of(2017, 6, 19), LocalDate.of(2017, 6, 18), LocalDate.of(2017, 6, 29)); // true
check(LocalDate.of(2017, 6, 17), LocalDate.of(2017, 6, 18), LocalDate.of(2017, 6, 29)); // false
check(LocalDateTime.of(2017, 6, 29, 9, 0), LocalDateTime.of(2017, 6, 29, 8, 0), LocalDateTime.of(2017, 6, 29, 11, 0)); // true
check(LocalDateTime.of(2017, 6, 29, 7, 0), LocalDateTime.of(2017, 6, 29, 8, 0), LocalDateTime.of(2017, 6, 29, 11, 0)); // false
You can extend the code to recognize other types, if you need (such as LocalTime
).
You could also add another parameter indicating what type will be used, like this:
public boolean check(Temporal dateFieldToCheck, Temporal minDate, Temporal maxDate, int type) {
switch (type) {
case 1:
// try to get as LocalDateTime
LocalDateTime dtCheck = LocalDateTime.from(dateFieldToCheck);
LocalDateTime dtMin = LocalDateTime.from(minDate);
LocalDateTime dtMax = LocalDateTime.from(maxDate);
return (!dtCheck.isBefore(dtMin)) && (!dtCheck.isAfter(dtMax));
case 2:
// trying a LocaDate instead
LocalDate dCheck = LocalDate.from(dateFieldToCheck);
LocalDate dMin = LocalDate.from(minDate);
LocalDate dMax = LocalDate.from(maxDate);
return (!dCheck.isBefore(dMin)) && (!dCheck.isAfter(dMax));
// ... and so on
}
// invalid type, return false?
return false;
}
So you could call it with a ZonedDateTime
and force it to use a LocalDate
(then you could adapt your code and call this method with the objects you've got from atZone(ZoneId.systemDefault())
):
ZonedDateTime z1 = obj.getDate(fc.getDateField()).toInstant().atZone(ZoneId.systemDefault());
ZonedDateTime z2 = context.getStartDate().toInstant().atZone(ZoneId.systemDefault());
ZonedDateTime z3 = context.getEndDate().toInstant().atZone(ZoneId.systemDefault());
check(z1, z2, z3, 2);
This code also works with different types:
ZonedDateTime z1 = ...
LocalDate d = ...
LocalDateTime dt = ...
// converts all to LocalDate
System.out.println(check(z1, dt, d, 2));
PS: of course you could create an Enum
instead of an int
to define the type. Or use a Class<? extends Temporal>
to directly indicate the type:
public boolean check(Temporal dateFieldToCheck, Temporal minDate, Temporal maxDate, Class<? extends Temporal> type) {
if (type == LocalDate.class) {
// code for LocalDate (use LocalDate.from() as above)
}
if (type == LocalDateTime.class) {
// code for LocalDateTime (use LocalDateTime.from() as above)
}
}
// convert all objects to LocalDate
check(z1, dt, d, LocalDate.class);