Местное время с 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
минутах от полуночи?
4 ответов
вместо проверки, если 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
экземпляр должен быть больше, чем у второго экземпляра. Это не true для 00:00
и 23:59
, следовательно, почему ваш метод возвращает false
. Такой же анализ можно сделать по LocalTime#isBefore
, и вы получите тот же результат.
имейте в виду, что вы можете просто проверить в отношении LocalTime.MIDNIGHT
если вы хотите быть точным, но я предполагаю, что вы рассматриваете любое время в течение 1-минутный диапазон должен быть "полночь" (включая секунды).
решение заключается в использовании ||
вместо &&
:
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
предполагает, что это времена в тот же день.
Если вам действительно нужно сделать это таким образом, он не может выполнить оба утверждения. Рассмотрите возможность использования or, этот код возвращает 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));
}
как уже объяснялось, вы должны использовать ||
вместо &&
. Я думаю, что более читаем, Если вы реорганизуете переменные в условии следующим образом:
public boolean isAtMidnight(LocalTime time) {
return ONE_MINUTE_BEFORE_MIDNIGHT.isBefore(time) || ONE_MINUTE_AFTER_MIDNIGHT.isAfter(time);
}
минуту до полночь до...