LocalTime между 23.59 и 00:01
Я хочу проверить, является ли LocalTime
полночь. Для этого случая использования полночь определяется как что-либо между 23:59
и 00:01
. Это диапазон 2 минуты.
private final LocalTime ONE_MINUTE_BEFORE_MIDNIGHT = LocalTime.of(23, 59, 0);
private final LocalTime ONE_MINUTE_AFTER_MIDNIGHT = LocalTime.of(0, 1, 0);
У меня есть метод
public boolean isAtMidnight(LocalTime time) {
return time.isAfter(ONE_MINUTE_BEFORE_MIDNIGHT)
&& time.isBefore(ONE_MINUTE_AFTER_MIDNIGHT);
}
Этот метод всегда возвращает false
. Даже для LocalTime.MIDNIGHT
. он должен, однако, вернуться к true
.
Как я могу проверить, является ли время +-1
минутой с полуночи?
Ответы
Ответ 1
Вместо того, чтобы проверять, прошло ли time
после 23:59
и до 00:01
, вы должны проверить, есть ли это после 23:59
или до 00:01
.
public boolean isAtMidnight(LocalTime time){
return time.isAfter(ONE_MINUTE_BEFORE_MIDNIGHT) || time.isBefore(ONE_MINUTE_AFTER_MIDNIGHT);
}
Если мы посмотрим на реализацию для LocalTime#isAfter
, мы увидим следующее:
public boolean isAfter(LocalTime other) {
return compareTo(other) > 0;
}
Просмотр LocalTime#compareTo
:
@Override
public int compareTo(LocalTime other) {
int cmp = Integer.compare(hour, other.hour);
if (cmp == 0) {
cmp = Integer.compare(minute, other.minute);
if (cmp == 0) {
cmp = Integer.compare(second, other.second);
if (cmp == 0) {
cmp = Integer.compare(nano, other.nano);
}
}
}
return cmp;
}
Мы видим, что два экземпляра LocalTime
сначала сравниваются по их часам, а затем по минутам, секундам и, наконец, наносекундам. Для LocalTime#compareTo
возвращает значение больше 0
чтобы удовлетворить LocalTime#isAfter
, час первого экземпляра LocalTime
должен быть больше, чем второй экземпляр. Это не относится к 00:00
и 23:59
, поэтому ваш метод возвращает false
. Такой же анализ можно сделать для LocalTime#isBefore
, и вы получите тот же результат.
Имейте в виду, что вы можете просто проверить с LocalTime.MIDNIGHT
если хотите быть точным, но я предполагаю, что вы рассматриваете любое время в пределах 1-минутного диапазона как "полночь" (включая секунды).
Ответ 2
Решение состоит в использовании ||
вместо &&
:
public boolean isAtMidnight(LocalTime time) {
return time.isAfter(ONE_MINUTE_BEFORE_MIDNIGHT) || time.isBefore(ONE_MINUTE_AFTER_MIDNIGHT);
}
Это настолько противоречиво, не так ли? Фокус в том, что 00:00:01
не после 23:59
, так что всегда будет терпеть неудачу. Это так, потому что LocalTime.isAfter
или LocalTime.isBefore
предполагает, что те времена в тот же день.
Ответ 3
Если вам действительно нужно это делать, он не может выполнять оба утверждения. Подумайте об использовании или, этот код возвращает true для меня:
public static void main(String[] args)
{
LocalTime ONE_MINUTE_BEFORE_MIDNIGHT = LocalTime.of(23, 59, 0);
LocalTime ONE_MINUTE_AFTER_MIDNIGHT = LocalTime.of(0, 1, 0);
LocalTime md = LocalTime.MIDNIGHT;
System.out.println(md.isBefore(ONE_MINUTE_AFTER_MIDNIGHT) || md.isAfter(ONE_MINUTE_BEFORE_MIDNIGHT));
}
Ответ 4
Как уже объяснялось, вы должны использовать ||
вместо &&
. Я думаю, это более читаемо, если вы реорганизовываете переменные в условии следующим образом:
public boolean isAtMidnight(LocalTime time) {
return ONE_MINUTE_BEFORE_MIDNIGHT.isBefore(time) || ONE_MINUTE_AFTER_MIDNIGHT.isAfter(time);
}
За одну минуту до полуночи до...