使用Java LocalTime锁定下溢/上溢

时间:2018-08-12 12:45:10

标签: java date java-8 java-time localtime

当从LocalTime对象中减去给定的数量时,我已经意识到会发生上溢/下溢。

示例:

00:30 - 35 minutes = 23:55
23:30 + 35 minutes = 00:05

对于我的应用程序,我希望锁定时间使上面的代码在下溢时生成00:00,在上溢时生成23:59

这可能吗?

2 个答案:

答案 0 :(得分:6)

我的建议是:

    LocalTime orig = LocalTime.of(0, 30);
    int minutesToSubtract = 35;
    long minutesSinceMidnight = ChronoUnit.MINUTES.between(LocalTime.MIN, orig);
    LocalTime result;
    if (minutesToSubtract > minutesSinceMidnight) {
        // Subtracting the minutes will pass midnight at start of day
        result = LocalTime.MIN;
    } else {
        // Normal case, no underflow
        result = orig.minusMinutes(minutesToSubtract);
    }
    System.out.println(result);

以上假设minutesToSubtract为非负数。如果可能出现负数,则需要检查下溢和上溢。

检查溢出(大于23:59:59.999999999)的情况与此类似。在一天结束时使用LocalTime.MAX

编辑:JB Nizet在他的注释中用于其他操作的代码应采用正确的代码格式,因此我将其粘贴在此处:

public static LocalTime addWithoutOverflow(LocalTime baseTime, int minutes) {
    LocalTime maxTime = LocalTime.MAX;
    long maxNanos = ChronoUnit.NANOS.between(baseTime, maxTime);
    long nanos = Duration.ofMinutes(minutes).toNanos();
    return baseTime.plusNanos(Math.min(maxNanos, nanos));
}

答案 1 :(得分:0)

在此示例中,路由应在开始之前锁定x时间。

1 |LocalTime firstStopTime = firstStop.getStopTime(); 
2 |LocalTime earliestTime = firstStopTime.minus(beforeRouteLockTimeMins % 1440, ChronoUnit.MINUTES);
3 |LocalTime latestTime = firstStopTime.plus(afterRouteTimeLockMins % 1440, ChronoUnit.MINUTES);
4 |
5 |// Handle underflow/overflow when getting earliest/latest time
6 |if (earliestTime.isAfter(firstStopTime)) earliestTime = LocalTime.MIN;
7 |if (latestTime.isBefore(firstStopTime)) latestTime = LocalTime.MAX;

在第2行和第3行,我使用%来避免锁定时间大于24小时。这种方式无论溢出/下溢,都无法通过原始时间,因此对第6行和第7行的检查将起作用。

然后我假设如果最早的减法实际上晚于停止,则它一定已经下溢,因此将其设置为00:00,然后将其设置为最新时间。

最后,可以这样比较时间:

// Check route is within time constraint
if (currentTime.isBefore(earliestTime)) {
    return new RouteAvailabilityResponseModel(false, "Too early to begin route.");
} else if (currentTime.isAfter(latestTime)) {
    return new RouteAvailabilityResponseModel(false, "Too late to begin route.");
} else {
    return new RouteAvailabilityResponseModel(true, "Route can be started.");
}

虽然此解决方案现在对我有用,但我想看看是否还有其他一些不太详细的选项。 (然后再次是Java。)