Java 获取事件之间的时间,用户希望获取两个事件之间的时间,如果需要将时间转换为人类可读的格式,使用时态类(temporal class)定义的 between
或 until
方法,或 Period
类定义的 between
方法以生成 Period
对象;如果不需要转换时间格式,则使用以秒和纳秒为单位对时间量进行建模的 Duration
类。
Java 获取事件之间的时间 问题描述
用户希望获取两个事件之间的时间。
Java 获取事件之间的时间 解决方案
如果需要将时间转换为人类可读的格式,使用时态类(temporal class)定义的 between
或 until
方法,或 Period
类定义的 between
方法以生成 Period
对象;如果不需要转换时间格式,则使用以秒和纳秒为单位对时间量进行建模的 Duration
类。
Java 获取事件之间的时间 具体实例
在 java.time.temporal
包中,TemporalUnit
接口由定义在同一个包中的 ChronoUnit
枚举实现。TemporalUnit
接口定义了一个名为 between
的方法,它传入两个 TemporalUnit
实例并返回二者之间的时间量(long
型数据):
long between(Temporal temporal1Inclusive,
Temporal temporal2Exclusive)
请注意,起始时间和终止时间的类型必须相互兼容。在计算时间量之前,实现将第二个类型转换为第一个类型的实例。如果终止时间早于起始时间,则结果为负。
between
方法的返回值是两个参数之间的完整“单位”数 11,这为使用 ChronoUnit
定义的枚举常量提供了便利。
11返回值为整数(whole number)。例如,15:00 和 16:59 之间的小时数为 1 小时,即便它和 2 小时只差 1 分钟。——译者注
例如,假设我们希望获取当天与今后某个特定日期之间的天数。由于需要处理的是天数,使用 ChronoUnit
定义的枚举常量 ChronoUnit.DAYS
,如例 8-40 所示。
例 8-40 计算当天到 2020 年美国选举日(11 月 3 日)之间的天数
LocalDate electionDay = LocalDate.of(2020, Month.NOVEMBER, 3);
LocalDate today = LocalDate.now();
System.out.printf("%d day(s) to go...%n",
ChronoUnit.DAYS.between(today, electionDay));
程序在 ChronoUnit.DAYS
上调用 between
方法,并返回两个日期之间的天数。ChronoUnit
定义的其他枚举常量包括 HOURS
、WEEKS
、MONTHS
、YEARS
、DECADES
、CENTURIES
等。12
12无论相信与否,ChronoUnit
中还包括一个名为 FOREVER
的枚举常量。如果读者在开发中确实用到了这个常量,请告诉作者,作者很想看看它的实际应用。(根据 Javadoc 的描述,FOREVER
是一个表示永恒概念的人造单位,通常与 TemporalField
一起使用,代表年份和时代这样的无界字段。——译者注)
1.java.time.Period
类
我们可以利用 Period
类将时间分解为符合人类阅读习惯的年、月、日格式。不少基本类的 until
方法都返回 Period
:
// java.time.LocalDate类
Period until(ChronoLocalDate endDateExclusive)
重写例 8-40,结果如例 8-41 所示。
例 8-41 通过
Period
类获取年、月、日
LocalDate electionDay = LocalDate.of(2020, Month.NOVEMBER, 3);
LocalDate today = LocalDate.now();
Period until = today.until(electionDay); ➊
years = until.getYears();
months = until.getMonths();
days = until.getDays();
System.out.printf("%d year(s), %d month(s), and %d day(s)%n",
years, months, days);
➊ 相当于 Period.between(today, electionDay)
从本例的注释可以看到,Period
类同样定义了一个名为 between
的静态方法,其用法与 until
方法并无区别。选择哪种样式均可,但应以有助于提高代码可读性为原则。
简而言之,如果需要将时间转换为人类可读的格式(如年、月、日),应使用 Period
类。
2.java.time.Duration
类
Duration
类表示以秒和纳秒为单位的时间量,通常与 Instant
一起使用,结果可以转换为许多其他类型。Duration
类存储一个表示秒的 long
型数据以及一个表示纳秒的 int
型数据。如果终点早于起点,则结果为负。
例 8-42 显示了如何利用 Duration
实现简单的计时。
例 8-42 对某个方法进行计时
public static double getTiming(Instant start, Instant end) {
return Duration.between(start, end).toMillis() / 1000.0;
}
Instant start = Instant.now();
// 调用需要计时的方法
Instant end = Instant.now();
System.out.println(getTiming(start, end) + " seconds");
这种对方法计时的手段并不高明,但胜在简单易行。
Duration
类定义了 toDays
、toHours
、toMillis
、toMinutes
、toNanos
等多种转换方法,这就是本例中 getTiming
方法使用 toMillis
并除以 1000 的原因。