当地时间 23.59 至 00:01 [已关闭]

2022-09-03 04:00:58

我想检查一个是否是午夜。对于此用例,午夜被定义为 介于 和 之间的任何内容。这是2分钟的范围。LocalTime23:5900:01

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);
}

此方法始终返回 。即使对于 .但是,它应该返回 。falseLocalTime.MIDNIGHTtrue

如何检查时间是否从午夜开始是分钟?+-1


答案 1

解决方案是使用代替 :||&&

public boolean isAtMidnight(LocalTime time) {
    return time.isAfter(ONE_MINUTE_BEFORE_MIDNIGHT) || time.isBefore(ONE_MINUTE_AFTER_MIDNIGHT);
}

这太违反直觉了,不是吗?诀窍是不要在之后,所以这总是会失败。之所以如此,是因为或假设这些是同一天的时间00:00:0123:59LocalTime.isAfterLocalTime.isBefore


答案 2

而不是检查 是否 在 之后 之前,您应该检查它是在 之后还是之前。time23:5900:0123:5900: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;
}

我们可以看到,两个实例首先按各自的小时进行比较,然后是分钟,然后是秒,最后是纳秒。要返回一个大于满足的值,第一个实例的小时数必须大于第二个实例的小时数。对于 和 则然,因此为什么您的方法返回 。可以对 执行相同的分析,您将获得相同的结果。LocalTimeLocalTime#compareTo0LocalTime#isAfterLocalTime00:0023:59falseLocalTime#isBefore

请记住,如果你想精确,你可以检查一下,但我假设你正在考虑1分钟范围内的任何时间都是“午夜”(包括秒)。LocalTime.MIDNIGHT


推荐