期限和期限

当您编写代码以指定时间时,请使用最能满足您需要的类或方法:Duration类,Period类或ChronoUnit.between方法。 Duration使用基于时间的值(秒,纳秒)来测量时间量。 Period使用基于日期的值(年,月,日)。

Note:

一天的Duration恰好是* 24 小时 Long。一天的Period当添加到ZonedDateTime时,可能会根据timezone而有所不同。例如,如果发生在夏令时的第一天或最后一天。

Duration

Duration最适合用于测量基于机器的时间的情况,例如使用Instant对象的代码。 Duration对象以秒或纳秒为单位进行测量,并且不使用基于日期的构造(例如年,月和日),尽管该类提供了转换为天,小时和分钟的方法。如果Duration是用在起点之前出现的 endpoints 创建的,则它可以具有负值。

以下代码以纳秒为单位计算两个瞬间之间的持续时间:

Instant t1, t2;
...
long ns = Duration.between(t1, t2).toNanos();

以下代码将Instant添加 10 秒:

Instant start;
...
Duration gap = Duration.ofSeconds(10);
Instant later = start.plus(gap);

Duration未连接到时间线,因为它不跟踪timezone或夏时制。在ZonedDateTime上加上等于 1 天的Duration会导致准确地添加 24 小时,而不考虑夏时制或其他可能导致的时差。

ChronoUnit

时间包中讨论的ChronoUnit枚举定义了用于测量时间的单位。 ChronoUnit\.between方法仅在单个时间单位(例如天或秒)中测量时间量时很有用。 between方法适用于所有基于时间的对象,但它仅以单个单位返回数量。以下代码计算两个时间戳之间的间隔(以毫秒为单位):

import java.time.Instant;
import java.time.temporal.Temporal;
import java.time.temporal.ChronoUnit;

Instant previous, current, gap;
...
current = Instant.now();
if (previous != null) {
    gap = ChronoUnit.MILLIS.between(previous,current);
}
...

Period

要使用基于日期的值(年,月,日)定义时间量,请使用Period类。 Period类提供了各种get方法,例如getMonthsgetDaysgetYears,因此您可以从时间段中提取时间量。

总时间由三个单位共同表示:月,天和年。要显示以单个时间单位(例如天)衡量的时间量,可以使用ChronoUnit\.between方法。

下面的代码报告您的年龄,假设您出生于 1960 年 1 月 1 日。Period类用于确定时间,以年,月和日为单位。使用ChronoUnit\.between方法确定同一时期(总计天数),并显示在括号中:

LocalDate today = LocalDate.now();
LocalDate birthday = LocalDate.of(1960, Month.JANUARY, 1);

Period p = Period.between(birthday, today);
long p2 = ChronoUnit.DAYS.between(birthday, today);
System.out.println("You are " + p.getYears() + " years, " + p.getMonths() +
                   " months, and " + p.getDays() +
                   " days old. (" + p2 + " days total)");

该代码产生类似于以下内容的输出:

You are 53 years, 4 months, and 29 days old. (19508 days total)

要计算到下一个生日为止的时间,您可以使用Birthday示例中的以下代码。 Period类用于确定以月和日为单位的值。 ChronoUnit\.between方法以总天数返回该值,并显示在括号中。

LocalDate birthday = LocalDate.of(1960, Month.JANUARY, 1);

LocalDate nextBDay = birthday.withYear(today.getYear());

//If your birthday has occurred this year already, add 1 to the year.
if (nextBDay.isBefore(today) || nextBDay.isEqual(today)) {
    nextBDay = nextBDay.plusYears(1);
}

Period p = Period.between(today, nextBDay);
long p2 = ChronoUnit.DAYS.between(today, nextBDay);
System.out.println("There are " + p.getMonths() + " months, and " +
                   p.getDays() + " days until your next birthday. (" +
                   p2 + " total)");

该代码产生类似于以下内容的输出:

There are 7 months, and 2 days until your next birthday. (216 total)

这些计算不考虑timezone差异。例如,如果您出生于澳大利亚,但目前居住在班加罗尔,则这会稍微影响您的确切年龄。在这种情况下,请将PeriodZonedDateTime类结合使用。将Period添加到ZonedDateTime时,会观察到时间差异。