5

我正在为 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,但我有点困惑,这本书是否给出了错误答案?

假设 NY 比 LA 早 3 小时,这是否意味着,例如,NY 是 5:00,然后 LA 是 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。

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

4

4 回答 4

4

Duration.between返回两个瞬间之间的差。对于LocalDateTime,这意味着正确的答案需要标准化时区。由于洛杉矶的同一本地时间于纽约,因此结果是肯定的。

纽约的早上 6:00,洛杉矶的凌晨 3:00,这意味着需要 3 个小时才能到达洛杉矶的早上 6:00。相反,洛杉矶的早上 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
于 2017-07-07T08:09:43.180 回答
0

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


}
于 2017-07-07T08:09:31.600 回答
0

另一种方法是将nyZdt和转换laZdtInstant.

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 IS NOT before start。Start is2017-12-02T11:00:00Z和 end is 2017-12-02T14:00:00Z,换句话说,LA 在 NY 之后,所以区别是:PT3H.

于 2017-11-07T09:52:58.163 回答
0

如果你被要求找出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

如您所见,nyZdt3几小时前laZd,因此持续时间是PT3H


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

于 2020-12-29T21:11:00.230 回答