Java 教程是为 JDK 8 编写的。本页中描述的示例和实践未利用在后续版本中引入的改进。
编写代码以指定时间量时,请使用最符合你需要的类或方法:Duration 类,Period 类,或 ChronoUnit.between 方法。Duration 使用基于时间的值(秒,纳秒)测量时间量。Period 使用基于日期的值(年,月,日)。
Duration 最适合测量基于机器的时间的情况,例如使用 Instant 对象的代码。Duration 对象以秒或纳秒为单位测量,并且不使用基于日期的构造,例如年,月和日,尽管该类提供了转换为天,小时和分钟的方法。如果 Duration 是使用在起点之前发生的终点创建的,则可以具有负值。
以下代码以纳秒为单位计算两个时刻之间的持续时间:
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 未连接到时间线,因为它不跟踪时区或夏令时。将 Duration 等于 1 天添加到 ZonedDateTime 会导致正好 24 小时的添加,无论夏令时或其他可能导致的时间差异如何。
The Temporal Package 中讨论的 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 类提供各种 get 方法,例如 getMonths,getDays,getYears,以便你可以从期间中提取时间。
总时间段由所有三个单元一起表示:月,日和年。要显示在单个时间单位(例如天)中测量的时间量,你可以使用 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)
这些计算不考虑时区差异。例如,如果你出生在澳大利亚,但目前住在班加罗尔,这会略微影响你确切年龄的计算。在这种情况下,将 Period 与 ZonedDateTime 类结合使用。将 Period 添加到 ZonedDateTime 时,会观察到时间差。