Another way of doing, complementing the response of diegofm, is you go subtracting the date fields one by one to remove from it, each component.
For example:
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.temporal.ChronoUnit;
class TesteDurationNovo {
public static void main(String[] args) {
LocalDateTime primeiraData = LocalDateTime.of(2017, Month.JANUARY, 10, 14, 00, 00);
LocalDateTime segundaDate = LocalDateTime.of(2016, Month.JANUARY, 10, 16, 30, 00);
Duration testeDuration = Duration.between(primeiraData, segundaDate);
long dias = testeDuration.toDays();
Duration d2 = testeDuration.minus(dias, ChronoUnit.DAYS);
long horas = d2.toHours();
Duration d3 = d2.minus(horas, ChronoUnit.HOURS);
long minutos = d3.toMinutes();
Duration d4 = d3.minus(minutos, ChronoUnit.MINUTES);
long segundos = d4.getSeconds();
Duration d5 = d4.minus(segundos, ChronoUnit.SECONDS);
long nanos = d5.toNanos();
Duration d6 = d5.minus(nanos, ChronoUnit.NANOS);
System.out.println("Total: " + dias + " dias, " + horas + " horas, " + minutos + " minutos, " + segundos + " segundos, " + nanos + " ns.");
System.out.println("Resultado: " + testeDuration.toString());
if (!d6.isZero()) throw new AssertionError(d6.toString());
}
}
Here’s the way out:
Total: -365 dias, -21 horas, -30 minutos, 0 segundos, 0 ns.
Resultado: PT-8781H-30M
This means that your period is 365 days, 21 hours and 30 minutes negative. The period is negative because the primeiraData
is after the segundaDate
. This can be arranged if you simply change the dates you assign to each variable, or if you change the order of the parameters in the method between(Temporal, Temporal)
, or even if you call the method abs()
of Duration
and only then store the result in the variable testeDuration
.
It is not possible to subtract months or years in a simple and direct way from the Duration
because not every month and not every year have the same size. That’s why there are no methods toMonths()
or toYears()
.
As to the outcome of toString()
, that PT-8781H-30M
means only that the duration is -8781 hours and -30 minutes. A String
returned will always contain the amount of hours, minutes and seconds of the Duration
, may be the number of fractional seconds for cases including nanoseconds and the number of hours for all practical purposes unlimited.
Already that if
at the end is just to make sure that the Duration
remaining after subtracting all fields is zero. If it were not, it would be because something wrong was happening in the above process, a fact that would then be denounced by the release of a AssertionError
.
See here working on ideone.
Ah, and if you change the primeiraData
for 2016 instead of 2017, you will get this result:
Total: 0 dias, 2 horas, 30 minutos, 0 segundos, 0 ns.
Resultado: PT2H30M
I believe that’s what you had when you got it PT2H30M
as an exit.
And if you are sure that your result will only be in hours and minutes, you could do that, similar to diegofm’s response:
System.out.println("Resultado: " + String.format("%d:%02d", horas, minutos));
However, this will not work if you have to consider hours, days, seconds or nanoseconds as well. It won’t work either if the period is negative. Therefore, you should look for what will work best for you considering the dates and periods your program will have to deal with.
This code does not give this result.
– user28595