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

时间:2016-12-10 15:29:55

标签: java date datetime java-8 timezone

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

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

3 个答案:

答案 0 :(得分:60)

您可以在ChronoUnit的之间使用方法。

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

onBlur

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

static long zonedDateTimeDifference(ZonedDateTime d1, ZonedDateTime d2, ChronoUnit unit){
    return unit.between(d1, d2);
}

但请记住,为混合 LocalDateTime ZonedDateTime 调用此方法会导致 DateTimeException

希望它有所帮助。

答案 1 :(得分:46)

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

多年,几个月,几天:

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

详细

Answer by Michal S是正确的,显示ChronoUnit

Duration& Period

另一条路线是DurationPeriod类。使用第一个时间较短(小时,分钟,秒),第二个时间更长(年,月,日)。

Duration d = Duration.between( zdtA , zdtB );

通过调用toStringstandard ISO 8601 format中生成字符串。格式为PnYnMnDTnHnMnS,其中P标记开头,T分隔两个部分。

String output = d.toString();

在Java 9及更高版本中,调用to…Part方法获取各个组件。在another Answer of mine讨论。

示例代码

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

Duration d = Duration.between( zdtStart , zdtStop );
  

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

     

PT3H7M

请参阅live code in IdeOne.com

Interval& LocalDateRange

ThreeTen-Extra项目为java.time类添加了功能。其中一个方便的类是Interval,表示时间跨度为时间轴上的一对点。对于一对LocalDateRange对象,另一个是LocalDate。相比之下,Period&每个Duration类代表一段时间,因为附加到时间轴上。

Interval的工厂方法需要一对Instant个对象。

Interval interval = Interval.of( zdtStart.toInstant() , zdtStop.toInstant() );

您可以从Duration获得Interval

Duration d = interval.toDuration();

关于 java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和& SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

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

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore

答案 2 :(得分:0)

这为您提供了两个 ZonedDateTimes 之间的分钟数。

int minutes = (int) (end.toEpochSecond() - start.toEpochSecond()) / 60;