文档

Java™教程
隐藏目录
时段和持续时间
路径:日期 时间
课程:标准日历

Period 和 Duration

当您编写代码来指定一段时间时,请使用最适合您需求的类或方法:Duration类、Period类或ChronoUnit.between方法。Duration类使用基于时间的值(秒、纳秒)来测量时间量。Period类使用基于日期的值(年、月、日)。


注意: 一天的Duration确切为24小时。一个Period加到一个ZonedDateTime上,根据时区可能会有所不同,例如发生在夏令时的第一天或最后一天。

Duration

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

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

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

以下代码将10秒添加到一个Instant中:

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

Duration与时间线无关,即它不会跟踪时区或夏令时。将等于1天的Duration添加到ZonedDateTime中将确切添加24小时,而不考虑夏令时或其他可能导致的时间差异。

ChronoUnit

ChronoUnit枚举在Temporal包中进行了讨论,它定义了用于测量时间的单位。当您想要以单个时间单位(如天或秒)来测量一段时间时,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类提供了各种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("你今年已经" + p.getYears() + "岁," + p.getMonths() +
                   "个月,并且" + p.getDays() +
                   "天了。 (总共" + p2 + "天)");

该代码生成类似以下的输出:

你今年已经53岁,4个月,并且29天了。 (总共19508天)

要计算距离你下一个生日还有多久,可以使用来自Birthday示例的以下代码。使用Period类确定月份和天数的值。 ChronoUnit.between方法返回总天数的值,并在括号中显示。

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

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

//如果今年已经过了你的生日,将年份加1。
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("距离你的下一个生日还有" + p.getMonths() + "个月," +
                   p.getDays() + "天。 (总共" +
                   p2 + "天)");

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

距离你的下一个生日还有7个月,2天。(总共216天)

这些计算没有考虑时区的差异。例如,如果你出生在澳大利亚,但目前居住在班加罗尔,这会对你的确切年龄计算有轻微影响。在这种情况下,可以使用Period结合ZonedDateTime类。当将Period添加到ZonedDateTime时,会考虑时间差异。


上一页:时间查询
下一页:时钟