您可以让您的方法接收一个asjava.time.temporal.Temporal
参数(或@JodaStephen 建议的一个)。此代码适用于两者。TemporalAccessor
我必须承认,我更愿意像@Lachezar Balev 的回答所暗示的那样去做,但无论如何,这是一个替代方案。
由于 aTemporal
可以是任何类型(LocalDate
、LocalDateTime
、ZonedDateTime
等),但您只需要LocalDate
and LocalDateTime
,我正在执行以下操作:
- 尝试创建
LocalDateTime
第一个:它需要比LocalDate
(小时/分钟/秒)更多的字段,所以如果可以创建,它是首选类型
- 如果无法创建,我会捕获相应的异常并尝试创建一个
LocalDate
另一个细节是我还简化了您的比较:
dateFieldToCheck.isAfter(minDate) || dateFieldToCheck.isEqual(minDate)
相当于:
! dateFieldToCheck.isBefore(minDate)
与 比较时进行了类似的简化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));
}
}
LocalDate
现在您可以使用 a和 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
如果需要(例如LocalTime
),您可以扩展代码以识别其他类型。
您还可以添加另一个参数来指示将使用的类型,如下所示:
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;
}
所以你可以用 a 调用它ZonedDateTime
并强制它使用 a LocalDate
(然后你可以调整你的代码并用你从中获得的对象调用这个方法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);
此代码也适用于不同的类型:
ZonedDateTime z1 = ...
LocalDate d = ...
LocalDateTime dt = ...
// converts all to LocalDate
System.out.println(check(z1, dt, d, 2));
PS:当然你可以创建一个Enum
而不是一个int
来定义类型。或者使用aClass<? extends Temporal>
直接表示类型:
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);