When Duration.between () in Java DateTime returns negative value
I am preaparing for a Java OCP test and there is a Java DateTime question in the mock test like this:
Given that New York is 3 hours ahead of Los Angeles, what's the next print code?
LocalDateTime ldt = LocalDateTime.of(2017, 12, 02, 6, 0, 0); ZonedDateTime nyZdt = ldt.atZone(nyZone); ZonedDateTime laZdt = ldt.atZone(laZone); Duration d = Duration.between(nyZdt, laZdt); System.out.println(d);
And the correct answer is PT3H, but I am a little confused if the book gives the wrong answer or not?
Given that NY is 3 hours ahead of Los Angeles, does this mean, for example, NY is 5:00 and then LA will be 2:00. So Duration.between (5,2) should be PT-3H, because according to the Javadoc:, The result of this method can be a negative period if the end is before the start. To guarantee to obtain a positive duration call abs() on the result.
and in this case "2" to "5" , so the result should be PT-3H, not PT3H.
Which one do you think is correct?
source to share
Duration.between
returns the difference between two moments. For LocalDateTime
this, it means that the correct answer requires normalizing time zones. Since the same local hour in Los Angeles is later than New York, the result is positive.
At 6:00 am in New York, at 3 am in Los Angeles, this means that until 3 o'clock in Los Angeles will last 3 hours. In contrast, at 6:00 am in Los Angeles, at 9:00 am in New York, which means that 3 o'clock is from 6:00 am NY.
LocalDateTime ldt = LocalDateTime.of(2017, 12, 02, 6, 0, 0);
ZonedDateTime nyZdt = ldt.atZone(nyZone); // 6:00 AM NY = 3:00 AM LA
ZonedDateTime laZdt = ldt.atZone(laZone); // 6:00 AM LA = 9:00 AM NY
Duration d = Duration.between(nyZdt, laZdt); // 9:00 AM NY - 6:00 AM NY = 3H OR 3:00 AM LA - 6:00 AM LA = 3H
source to share
3 o'clock is correct. Just run the code.
@Test
public void test1() throws Exception {
LocalDateTime ldt = LocalDateTime.of(2017, 12, 02, 6, 0, 0);
ZonedDateTime nyZdt = ldt.atZone(ZoneId.of("America/New_York"));
ZonedDateTime laZdt = ldt.atZone(ZoneId.of("America/Los_Angeles"));
Duration d = Duration.between(nyZdt, laZdt);
System.out.println(d.toHours());
}
source to share
Another approach is to transform nyZdt
and laZdt
to Instant
.
LocalDateTime ldt = LocalDateTime.of(2017, 12, 02, 6, 0, 0);
ZoneId nyZone = ZoneId.of("America/New_York");
ZonedDateTime nyZdt = ldt.atZone(nyZone);
System.out.println(nyZdt.toInstant()); //Prints 2017-12-02T11:00:00Z
ZoneId laZone = ZoneId.of("America/Los_Angeles");
ZonedDateTime laZdt = ldt.atZone(laZone);
System.out.println(laZdt.toInstant()); //Prints 2017-12-02T14:00:00Z
Duration d = Duration.between(nyZdt, laZdt);
System.out.println(d); //Prints PT3H
In this example, you can see more clearly why the minus sign is not showing up in your view. As you can see end
IS NOT before start
. The beginning 2017-12-02T11:00:00Z
and the end - 2017-12-02T14:00:00Z
, in other words, LA - after NY, so the difference: . PT3H
source to share