Java 8:计算两个ZonedDateTime之间的差异

Mag*_*ill 58 java timezone datetime date java-8

我正在尝试编写一种方法来打印两个ZonedDateTime之间的时差,关于时区之间的差异.

我找到了一些解决方案,但所有这些解决方案都是用LocalDateTime编写的.

Mic*_*zyk 69

您可以使用方法之间ChronoUnit.

此方法将这些时间转换为相同的区域(来自第一个参数的区域),然后调用直到Temporal接口中声明的方法:

static long zonedDateTimeDifference(ZonedDateTime d1, ZonedDateTime d2, ChronoUnit unit){
    return unit.between(d1, d2);
}
Run Code Online (Sandbox Code Playgroud)

由于ZonedDateTimeLocalDateTime都实现了Temporal接口,因此您还可以为这些日期时间类型编写通用方法:

static long dateTimeDifference(Temporal d1, Temporal d2, ChronoUnit unit){
    return unit.between(d1, d2);
}
Run Code Online (Sandbox Code Playgroud)

但请记住,为混合的LocalDateTimeZonedDateTime调用此方法会导致DateTimeException.

希望能帮助到你.


Bas*_*que 60

TL;博士

小时,分钟,秒:

Duration.between( zdtA , zdtB )  // Represent a span-of-time in terms of days (24-hour chunks of time, not calendar days), hours, minutes, seconds. Internally, a count of whole seconds plus a fractional second (nanoseconds).
Run Code Online (Sandbox Code Playgroud)

多年,几个月,几天:

Period.between(                  // Represent a span-of-time in terms of years-months-days. 
    zdtA.toLocalDate() ,         // Extract the date-only from the date-time-zone object. 
    zdtB.toLocalDate() 
)
Run Code Online (Sandbox Code Playgroud)

细节

Michal S回答是正确的,显示出来ChronoUnit.

Duration & Period

另一条路线是DurationPeriod班级.使用第一个用于较短的时间跨度(小时,分钟,秒),第二个用于较长的时间(年,月,日).

Duration d = Duration.between( zdtA , zdtB );
Run Code Online (Sandbox Code Playgroud)

通过调用生成标准ISO 8601格式的String toString.格式是PnYnMnDTnHnMnS其中P标记的开始和T两个部分分开.

String output = d.toString();
Run Code Online (Sandbox Code Playgroud)

在Java 9及更高版本中,调用to…Part方法来获取各个组件.我的另一个答案讨论过.

示例代码

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdtStart = ZonedDateTime.now( z );
ZonedDateTime zdtStop = zdtStart.plusHours( 3 ).plusMinutes( 7 );

Duration d = Duration.between( zdtStart , zdtStop );
Run Code Online (Sandbox Code Playgroud)

2016-12-11T03:07:50.639-05:00 [美国/蒙特利尔] /2016-12-11T06:14:50.639-05:00 [美/蒙特利尔]

PT3H7M

请参阅IdeOne.com中的实时代码.

Interval & LocalDateRange

ThreeTen-EXTRA项目将功能添加到java.time类.其中一个方便的类是Interval将时间跨度表示为时间轴上的一对点.另一个是LocalDateRange,对于一对LocalDate物体.相比之下,Period&Durationclasses表示附加到时间轴的时间跨度.

Interval采用一对Instant对象的工厂方法.

Interval interval = Interval.of( zdtStart.toInstant() , zdtStop.toInstant() );
Run Code Online (Sandbox Code Playgroud)

你可以Duration从一个Interval.

Duration d = interval.toDuration();
Run Code Online (Sandbox Code Playgroud)

关于java.time

java.time框架是建立在Java 8和更高版本.这些类取代麻烦的老传统日期时间类,如java.util.Date,Calendar,和SimpleDateFormat.

现在处于维护模式Joda-Time项目建议迁移到java.time类.

要了解更多信息,请参阅Oracle教程.并搜索Stack Overflow以获取许多示例和解释.规范是JSR 310.

您可以直接与数据库交换java.time对象.使用符合JDBC 4.2或更高版本的JDBC驱动程序.不需要字符串,不需要课程.java.sql.*

从哪里获取java.time类?

ThreeTen-额外项目与其他类扩展java.time.该项目是未来可能添加到java.time的试验场.您可以在此比如找到一些有用的类Interval,YearWeek,YearQuarter,和更多.