当 Java DateTime 中的 Duration.between() 返回负值时



我正在准备Java OCP测试,在模拟测试中有一个关于Java DateTime的问题,如下所示:

鉴于纽约比洛杉矶早 3 小时,将 以下代码打印?

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);

正确答案是 PT3H,但我在这里有点困惑,这本书是否给出了错误的答案?

假设纽约比洛杉矶早 3 小时,这是否意味着,例如,纽约是 5:00,然后洛杉矶将是 2:00。所以 Duration.between(5,2( 应该是 PT-3H,因为根据 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.,在这种情况下,"2" 在"5">之前,所以结果应该是 PT-3H而不是 PT3H。

你怎么看,哪一个是正确的?

Duration.between返回两个时刻之间的差值。对于LocalDateTime,这意味着正确的答案需要规范化时区。由于洛杉矶的同一当地时间比纽约晚,因此结果是积极的。

纽约的 6:00 AM 是洛杉矶的 3:00 AM,这意味着 3 小时将过去,直到洛杉矶的 6:00 AM。 相反,洛杉矶的上午 6:00 是纽约的上午 9:00,这意味着自纽约上午 6:00 以来已经过去了 3 个小时。

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

3小时是正确的。只需运行代码即可。

@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());

}

另一种方法是将nyZdtlaZdt转换为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

在此示例中,您可以更清楚地看到为什么减号没有出现在输出中。如您所见,end不是start之前。开始是2017-12-02T11:00:00Z,结束是2017-12-02T14:00:00Z,换句话说,洛杉矶在NY之后,所以区别是:PT3H

如果要求您找到2 km 300 m1 和1020 m 45 cm之间的区别,您会怎么做?

您的答案 :我将以相同的单位转换每个距离,然后从另一个中减去一个。

这正是您需要做的,以便理解和解决此问题。您需要将两个日期时间转换为相同的时区,然后找到持续时间。

ZonedDateTime#withZoneSameInstant

使用它来获取具有不同时区的ZonedDateTime的副本,并保留即时时间。简单来说,它将返回目标时区的本地日期时间。

演示:

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
ZoneId nyZone = ZoneId.of("America/New_York");
ZoneId laZone = ZoneId.of("America/Los_Angeles");
LocalDateTime ldt = LocalDateTime.of(2017, 12, 02, 6, 0, 0);
ZonedDateTime nyZdt = ldt.atZone(nyZone);
ZonedDateTime laZdt = ldt.atZone(laZone);
System.out.println("laZd ----------------------------> " + laZdt);
// Convert the nyZdt to LA date-time
ZonedDateTime nyZdtConverted = nyZdt.withZoneSameInstant(laZone);
System.out.println("nyZdt converted to LA date-time -> " + nyZdtConverted);
Duration d = Duration.between(nyZdt, laZdt);
System.out.println(d);
d = Duration.between(nyZdtConverted, laZdt);
System.out.println(d);
}
}

输出:

laZd ----------------------------> 2017-12-02T06:00-08:00[America/Los_Angeles]
nyZdt converted to LA date-time -> 2017-12-02T03:00-08:00[America/Los_Angeles]
PT3H
PT3H

如您所见,nyZdt是在laZd3小时,因此持续时间是PT3H.

<小时 />

1公里代表公里,m代表米,厘米代表厘米

相关内容

  • 没有找到相关文章

最新更新