Искам да проверя дали 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
минута от полунощ?
Отговори:
17 за отговор № 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
инстанцията трябва да е по-голяма от втората инстанция „Това е не true for 00:00
и 23:59
, следователно защо вашият метод се връща false
, Същият анализ може да се направи и за LocalTime#isBefore
, и вие ще стигнете до същия резултат.
Имайте предвид, че можете просто да проверите срещу LocalTime.MIDNIGHT
ако искате да бъдете точни, но предполагам, че "обмисляте всеки момент в рамките на 1-минутен интервал да бъде" полунощ "(включително секунди).
15 за отговор № 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 за отговор № 3
Ако наистина трябва да направите това по този начин, той не може да изпълни и двете твърдения. Помислете за използване или, този код връща вярно за мен:
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));
}
2 за отговор № 4
Както вече беше обяснено, трябва да използвате ||
вместо &&
, Мисля, че е по-четимо, ако реорганизирате променливите в състоянието по този начин:
public boolean isAtMidnight(LocalTime time) {
return ONE_MINUTE_BEFORE_MIDNIGHT.isBefore(time) || ONE_MINUTE_AFTER_MIDNIGHT.isAfter(time);
}
Една минута преди полунощ е преди...