Another way of doing, complementing diegofm response , is to go subtracting the date one fields to 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 output:
Total: -365 dias, -21 horas, -30 minutos, 0 segundos, 0 ns.
Resultado: PT-8781H-30M
This means your period is 365 days, 21 hours, and 30 minutes negatives . The period is negative because primeiraData
is after segundaDate
. This can be fixed if you simply change the dates you assign to each variable, or if you change the order of the parameters in the between(Temporal, Temporal)
", or if you call the abs()
of Duration
and then store the result in the testeDuration
variable %.
It is not possible to subtract months or years in a simple and direct way from Duration
because not every month and every year is the same size. That is why there are no methods toMonths()
or toYears()
.
As for the result of toString()
, this PT-8781H-30M
only means that the duration is -8781 hours and -30 minutes. The% returned% will always contain the amount of hours, minutes, and seconds of String
, which can be the fraction of seconds for cases that include nanoseconds and the amount of hours for all unlimited practical effects.
Since this Duration
at the end is just to make sure that if
remaining after subtracting all fields is zero. If it were not, it would be because something wrong would be happening in the above process, a fact that would then be denounced by the launch of a Duration
.
See here working on ideone.
Oh, and if you change the AssertionError
to 2016 instead of 2017, you get this result:
Total: 0 dias, 2 horas, 30 minutos, 0 segundos, 0 ns.
Resultado: PT2H30M
I think this is what you had when you got primeiraData
as output.
And if you're sure that your result will be only in hours and minutes, you could do that, similar to diegofm's answer:
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 also will not work if the period is negative. So you should look for what works best for you by considering the dates and times that your program will have to deal with.