When subtracting a given amount from a LocalTime object, I've realised that overflow/underflow can occur.
Example:
00:30 - 35 minutes = 23:55
23:30 + 35 minutes = 00:05
For my application, I would like lock times such that the above would generate 00:00
on underflow, and 23:59
on overflow.
Is this possible?
My suggestion is:
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);
The above assumes that minutesToSubtract
is non-negative. If negative numbers may occur, you need to check for both underflow and overflow.
The case of checking for overflow (more than 23:59:59.999999999
) is similar. Use LocalTime.MAX
for end of day.
Edit: JB Nizet's code for the other operation in his comment deserves proper code formatting, so I am pasting it here:
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));
}
In this example, a route should be locked x amount of time before it starts.
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;
On line 2 and 3, I am using % to avoid the lock time being greater than 24 hours. This way regardless of overflow/underflow, it can't pass the original time, so the checks on lines 6 and 7 will work.
I then assume that if the subtraction for earliest time is actually later than the stop, then it must have underflowed, therefore set it to 00:00, and the reverse for the latest time.
Finally, the times can be compared like so:
// 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.");
}
Whilst this solution is working for me right now, I would like to see if there are any other less verbose options. (Then again this is Java.)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.