Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当Java DateTime中的Duration.between()返回负值时_Java_Datetime_Duration_Timezone Offset_Jsr310 - Fatal编程技术网

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

当Java DateTime中的Duration.between()返回负值时,java,datetime,duration,timezone-offset,jsr310,Java,Datetime,Duration,Timezone Offset,Jsr310,我正在准备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 = Durat

我正在准备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:
的说法,如果结束在开始之前,那么这个方法的结果可能是一个负周期。为了保证在结果上获得正的持续时间,调用abs()。
,在这种情况下,“2”在“5”之前是,因此结果应该是PT-3H,而不是PT3H


你认为哪一个是正确的?

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


}

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

纽约的早上6点,洛杉矶的凌晨3点,这意味着洛杉矶的凌晨6点将持续3个小时。 相反,洛杉矶的早上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

另一种方法是将
nyZdt
laZdt
转换为
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
,换句话说,LA在NY之后,所以区别是:
PT3H

如果你被要求找出
2公里300米
1和
1020米45厘米
之间的区别,你该怎么办

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

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

使用它可以获得不同时区的
ZoneDateTime
副本,并保留即时消息。简单来说,它将返回目标时区中的本地日期时间

演示:

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
输出:

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
laZd
早3个小时,因此持续时间是
PT3H



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

洛杉矶是早上6点,纽约是早上9点。所以洛杉矶的早上6点发生在纽约的早上6点后3小时。在一个次要的nit上:除非你真的想用八进制写,否则不要用零作为整数的前缀。在你的例子中,
nyZdt
=纽约的早上6点,也就是在
laZdt
=洛杉矶的早上6点之前3小时,因此,结束并不早于开始。找出这本书是否正确的最好方法是运行代码(剧透警报:)。有趣的是,他们将月份的日期作为八进制值,
02
。在这种情况下,这没有什么区别(但本月8日必须写为
010
)。虽然这在技术上可能是正确的,但这并不是问题的答案,问题的答案明确指出:“鉴于纽约比洛杉矶早3小时,下面的代码将打印什么?”