当 Duration.between() in Java DateTime return 负值时
When the Duration.between() in Java DateTime return negative value
我正在准备 Java OCP 测试,在模拟测试中有一个关于 Java DateTime 的问题,如下所示:
Given that New York is 3 hours ahead of Los Angeles, what will the
following code print?
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" 是 before "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
returns 两个瞬间的区别。对于 LocalDateTime
,这意味着正确答案需要规范化时区。由于洛杉矶的同一当地时间比纽约晚 ,因此结果是肯定的。
纽约 6:00 上午,洛杉矶 3:00 上午,这意味着 3 小时将过去,直到洛杉矶 6:00 上午。
相反,洛杉矶 6:00 AM,纽约 9:00 AM,这意味着自纽约 6:00 AM 以来已经过去了 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
。 Start是2017-12-02T11:00:00Z
,end是2017-12-02T14:00:00Z
,也就是说LA在NY之后,所以区别就是:PT3H
.
如果让你找出 2 km 300 m
1 和 1020 m 45 cm
之间的区别,你会怎么做?
你的回答:我会将每个距离换算成相同的单位然后减去一个接一个。
这正是您理解和解决此问题所需要做的。您需要将两个日期时间转换为 相同的 时区,然后找到持续时间。
ZonedDateTime#withZoneSameInstant
使用它来获取具有不同时区的 ZonedDateTime
的副本,保留瞬间。简而言之,它将 return 您目标时区的本地日期时间。
演示:
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代表厘米
我正在准备 Java OCP 测试,在模拟测试中有一个关于 Java DateTime 的问题,如下所示:
Given that New York is 3 hours ahead of Los Angeles, what will the following code print?
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" 是 before "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
returns 两个瞬间的区别。对于 LocalDateTime
,这意味着正确答案需要规范化时区。由于洛杉矶的同一当地时间比纽约晚 ,因此结果是肯定的。
纽约 6:00 上午,洛杉矶 3:00 上午,这意味着 3 小时将过去,直到洛杉矶 6:00 上午。 相反,洛杉矶 6:00 AM,纽约 9:00 AM,这意味着自纽约 6:00 AM 以来已经过去了 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
。 Start是2017-12-02T11:00:00Z
,end是2017-12-02T14:00:00Z
,也就是说LA在NY之后,所以区别就是:PT3H
.
如果让你找出 2 km 300 m
1 和 1020 m 45 cm
之间的区别,你会怎么做?
你的回答:我会将每个距离换算成相同的单位然后减去一个接一个。
这正是您理解和解决此问题所需要做的。您需要将两个日期时间转换为 相同的 时区,然后找到持续时间。
ZonedDateTime#withZoneSameInstant
使用它来获取具有不同时区的 ZonedDateTime
的副本,保留瞬间。简而言之,它将 return 您目标时区的本地日期时间。
演示:
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代表厘米