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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41077142/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 23:08:18  来源:igfitidea点击:

Java 8: Calculate difference between two ZonedDateTime

javadatedatetimejava-8timezone

提问by Maggie Hill

I'm trying to write a method to print the time difference between two ZonedDateTimes, regarding the difference between time zones.

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

I found some solutions but all of them were written to work with LocalDateTime.

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

采纳答案by Micha? Szewczyk

You can use method betweenfrom ChronoUnit.

您可以使用方法之间ChronoUnit

This method converts those times to same zone (zone from the first argument) and after that, invokes untilmethod declared in Temporalinterface:

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

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

Since both ZonedDateTimeand LocalDateTimeimplements Temporalinterface, you can write also universal method for those date-time types:

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

static long dateTimeDifference(Temporal d1, Temporal d2, ChronoUnit unit){
    return unit.between(d1, d2);
}

But keep in mind, that invoking this method for mixed LocalDateTimeand ZonedDateTimeleads to DateTimeException.

Hope it helps.

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

希望能帮助到你。

回答by Basil Bourque

tl;dr

tl;博士

For hours, minutes, seconds:

对于小时、分钟、秒:

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

For years, months, days:

年、月、日:

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

Details

细节

The Answer by Michal Sis correct, showing ChronoUnit.

Michal S答案是正确的,显示ChronoUnit

Duration& Period

Duration& Period

Another route is the Durationand Periodclasses. Use the first for shorter spans of time (hours, minutes, seconds), the second for longer (years, months, days).

另一种途径是DurationPeriod类。第一个用于较短的时间跨度(小时、分钟、秒),第二个用于较长时间(年、月、日)。

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

Produce a String in standard ISO 8601 formatby calling toString. The format is PnYnMnDTnHnMnSwhere the Pmarks the beginning and Tseparates the two portions.

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

String output = d.toString();

In Java 9 and later, call the to…Partmethods to get the individual components. Discussed in another Answer of mine.

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

Example code

示例代码

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[America/Montreal]/2016-12-11T06:14:50.639-05:00[America/Montreal]

PT3H7M

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

PT3H7M

See live code in IdeOne.com.

在 IdeOne.com 中查看实时代码

Interval& LocalDateRange

Interval& LocalDateRange

The ThreeTen-Extraproject adds functionality to the java.time classes. One of its handy classes is Intervalto represent a span of time as a pair of points on the timeline. Another is LocalDateRange, for a pair of LocalDateobjects. In contrast, the Period& Durationclasses each represent a span of time as notattached to the timeline.

ThreeTen-EXTRA项目将功能添加到java.time类。它的一个方便的类是Interval将时间跨度表示为时间线上的一对点。另一个是LocalDateRange,用于一对LocalDate对象。相比之下,Period&Duration类每个都代表一个时间跨度,而不是附加到时间线。

The factory method for Intervaltakes a pair of Instantobjects.

的工厂方法Interval接受一对Instant对象。

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

You can obtain a Durationfrom an Interval.

您可以DurationInterval.

Duration d = interval.toDuration();


Table of span-of-time classes in Java and in the ThreeTen-Extra project

Java 和 ThreeTen-Extra 项目中的时间跨度类表



About java.time

关于java.time

The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat

The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.

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

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

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

You may exchange java.timeobjects directly with your database. Use a JDBC drivercompliant with JDBC 4.2or later. No need for strings, no need for java.sql.*classes.

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

Where to obtain the java.time classes?

从哪里获得 java.time 类?

The ThreeTen-Extraproject extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多