I'm developing an app in which I'm using Java8 Time. I'm facing an issue.
Let's say Time A is 08:00 and Time B is 17:00, so the difference of between these two times will be 9h which in my case is correct, but if Time A is 18:00 and Time B is 02:00 it should be 8h, but in my case my program is returning -16. Kindly someone guide me how to solve this.
My code:
@Test
public void testTime()
{
DateTimeFormatter format = DateTimeFormatter.ofPattern("HH:mm");
String s = "18:00";
String e = "02:00";
// Parse datetime string to java.time.LocalDateTime instance
LocalTime startTime = LocalTime.parse(s, format);
LocalTime endTime = LocalTime.parse(e, format);
String calculatedTime = ChronoUnit.HOURS.between(startTime, endTime)%24 + ":"
+ ChronoUnit.MINUTES.between(startTime, endTime)%60;
System.out.println(calculatedTime);
}
Why not use the Duration
class? It’s meant for situations like yours.
Duration calculatedTime = Duration.between(startTime, endTime);
if (calculatedTime.isNegative()) {
calculatedTime = calculatedTime.plusDays(1);
}
System.out.println(calculatedTime);
This prints the duration in ISO 8601 format:
PT8H
To format it in Java 8:
long hours = calculatedTime.toHours();
calculatedTime = calculatedTime.minusHours(hours);
String formattedTime = String.format(Locale.getDefault(), "%d:%02d",
hours, calculatedTime.toMinutes());
System.out.println(formattedTime);
This prints
8:00
To format in Java 9 (not tested):
String formattedTime = String.format("%d:%02d",
calculatedTime.toHoursPart(),
calculatedTime.toMinutesPart());
If the time difference comes out negative, then add 24.
Simples!
(Obviously this will ignore overnight changes to daylight saving time, so your best bet really is to do this properly using time duration objects. That said though, you'll then need to know more about the dates associated with the two times.)
You have to calculate time differences modulo 24
.
So take the difference as you already do and then compute it modulo 24
. Note that in Java -16%24
would return -16
so what you really need to do is the following:
public static int modulus(int n, int m){
return (n < 0) ? (m - (Math.abs(n) % m) ) %m : (n % m);
}
which always return a positive result.
check if the startTime is after endTime and swap the opernads if required:
LocalTime startTime = LocalTime.parse(s, format);
LocalTime endTime = LocalTime.parse(e, format);
String calculatedTimeMorning;
if (startTime.isAfter(endTime)) {
calculatedTimeMorning = (ChronoUnit.HOURS.between(endTime, startTime) % 24) + ":"
+ (ChronoUnit.MINUTES.between(endTime, startTime) % 60);
} else {
calculatedTimeMorning = (ChronoUnit.HOURS.between(startTime, endTime) % 24) + ":"
+ (ChronoUnit.MINUTES.between(startTime, endTime) % 60);
}