上一篇我们聊了时间单位抽象出的接口TemporalUnit,今天我们来聊时间段抽象出的接口TemporalAmount及其实现类Duration和Period。
实例化emporalAmount的实现类Duration和Period
与TemporalUnit的实现类ChronoUnit是一个枚举类不同,枚举类不需要我们构造生成对象,而Duration和Period我们则需要从构造一个该类的对象说起,才能顺利使用其各种方法,当然静态方法不用对象就可以。
实例化Duration
先说如何得到Duration的对象,第一个想到的就是构造方法,咱们先看Duration的成员变量,
根据文档解释,关键的两个成员变量是这个seconds和nanos,构造方法如下但却是private,
所以我们通常用另外几个常用的静态方法获得Duration对象,代码如下
//Duration对象表示两个Temporal间的一段时间
//static Duration between(Temporal startInclusive, Temporal endExclusive) 获取一个 Duration表示两个时间对象之间的持续时间。
Duration between1 = Duration.between(Instant.parse("2022-02-02T02:02:02.0Z"), Instant.parse("2022-02-02T02:02:03.000000001Z"));
Duration between2 = Duration.between(LocalDateTime.of(2022, 2, 2, 2, 2, 2, 2),
LocalDateTime.of(2022, 2, 2, 2, 2, 3, 3));
Duration between3 = Duration.between(LocalTime.of(2, 2, 2, 2),
LocalTime.of(2, 2, 2, 2));
// Duration between3 = Duration.between(LocalDate.of(2022, 2, 2), LocalDate.of(2022, 2, 2));//java.time.temporal.UnsupportedTemporalTypeException: Unsupported unit: Seconds
//从一个文本字符串获得一个 Duration
Duration parse = Duration.parse("PT1.000000001S");
//从时间量获取一个 Duration的实例
Duration from = Duration.from(parse);
// Duration from = Duration.from(Period.of(2, 2, 2));//java.time.temporal.UnsupportedTemporalTypeException: Unit must not have an estimated duration
//从时间单位和数量获取Duration的实例
Duration of = Duration.of(1, ChronoUnit.DAYS);
Duration of1 = Duration.of(1, ChronoUnit.HOURS);
Duration of2 = Duration.of(1, ChronoUnit.MINUTES);
Duration of3 = Duration.of(1, ChronoUnit.SECONDS);
Duration of4 = Duration.of(1, ChronoUnit.MILLIS);
Duration of5 = Duration.of(1, ChronoUnit.NANOS);
Duration duration = Duration.ofDays(1);
Duration duration1 = Duration.ofHours(1);
Duration duration4 = Duration.ofMinutes(1);
Duration duration3 = Duration.ofSeconds(1);
Duration duration2 = Duration.ofMillis(1);
Duration duration5 = Duration.ofNanos(1);
实例化Period
然后再看TemporalAmount另一个实现类Period,与Duration的以秒和纳秒为单位建立数量或时间量相比,Period以年,月和日为单位建立数量或时间量。
与Duration一样,Period的构造方法也是私有的
所以我们通常用另外几个常用的静态方法获得Period对象,代码如下
//static Period between(LocalDate startDateInclusive, LocalDate endDateExclusive) 获得一个 Period ,由两个日期之间的年数,月份和日期组成。
Period between3 = Period.between(LocalDate.of(2022, 2, 2),
LocalDate.of(2023, 3, 3));
//从一个文本字符串获得一个 Period
Period period = Period.parse("P1Y1M1D");
//static Period from(TemporalAmount amount) 从时间量获取一个 Period的实例。
Period from = Period.from(Period.of(1, 1, 1));
//从时间单位和数量获取Period的实例
Period of = Period.of(1, 1, 1);
Period period1 = Period.ofYears(1);
Period period2 = Period.ofMonths(1);
Period period3 = Period.ofWeeks(1);
Period period4 = Period.ofDays(1);
总也对比一下Duration和Period的这四个获得实例的方法,有两个注意点:一个是between方法,Duration的参数是Temporal类型,可以是Instant,LocalDateTime,LocalTime(LocalDate会报错),但是Period指定是LocalDate;另一个是from方法,虽然参数是TemporalAmount类型,但是只能从彼此自己的实例对象的时间量获得实例。
接口TemporalAmount常用方法
接下来我们看接口TemporalAmount的常用方法
这四个常用方法代码如下
//Duration , Period
Duration du = Duration.between(LocalDateTime.of(2022, 2, 2, 2, 2, 2, 2),
LocalDateTime.of(2022, 2, 2, 2, 3, 3, 3));
Period pe = Period.of(1, 1, 1);
//List<TemporalUnit> getUnits() 返回唯一定义此TemporalAmount值的单位列表。
List<TemporalUnit> units = du.getUnits();
List<TemporalUnit> units1 = pe.getUnits();
// long get(TemporalUnit unit) 返回请求的单位的值。
long l5 = du.get(ChronoUnit.SECONDS);
long l8 = du.get(ChronoUnit.NANOS);
long l10 = pe.get(ChronoUnit.YEARS);
long l11 = pe.get(ChronoUnit.MONTHS);
long l13 = pe.get(ChronoUnit.DAYS);
//Temporal addTo(Temporal temporal) 添加到指定的时间对象。
Temporal temporal1 = du.addTo(Instant.now());
Temporal temporal2 = du.addTo(LocalDateTime.now());
// Temporal temporal3 = du.addTo(LocalDate.now());
Temporal temporal4 = du.addTo(LocalTime.now());
// Temporal temporal5 = pe.addTo(Instant.now());
Temporal temporal6 = pe.addTo(LocalDateTime.now());
Temporal temporal7 = pe.addTo(LocalDate.now());
// Temporal temporal8 = pe.addTo(LocalTime.now());
//Temporal subtractFrom(Temporal temporal) 从指定的时间对象中减去此对象。
Temporal temporal9 = du.subtractFrom(Instant.now());
Temporal temporal10 = du.subtractFrom(LocalDateTime.now());
// Temporal temporal11 = du.subtractFrom(LocalDate.now());
Temporal temporal12 = du.subtractFrom(LocalTime.now());
// Temporal temporal13 = pe.subtractFrom(Instant.now());
Temporal temporal14 = pe.subtractFrom(LocalDateTime.now());
Temporal temporal15 = pe.subtractFrom(LocalDate.now());
// Temporal temporal16 = pe.subtractFrom(LocalTime.now());
这里需要注意的是,接口TemporalAmount的substract方法和add方法调用的是其参数的plus方法,所以注释掉的那些语句都是会抛出异常的。
Duration常用方法
Duration duration = Duration.between(LocalDateTime.of(2022, 2, 2, 2, 2, 2, 2),
LocalDateTime.of(2023, 3, 3, 3, 3, 3, 3));
long seconds = duration.getSeconds();
int nano = duration.getNano();
long l = duration.toDays();
long l1 = duration.toHours();
long l3 = duration.toMinutes();
long l2 = duration.toMillis();
long l4 = duration.toNanos();
Duration plus = duration.plus(Duration.ofDays(1));
Duration plus1 = duration.plus(1, ChronoUnit.DAYS);
Duration plusDays = duration.plusDays(1);
Duration plusHours = duration.plusHours(1);
Duration plusMinutes = duration.plusMinutes(1);
Duration plusSeconds = duration.plusSeconds(1);
Duration plusMillis = duration.plusMillis(1);
Duration plusNanos = duration.plusNanos(1);
Duration minus = duration.minus(Duration.ofDays(1));
Duration minus1 = duration.minus(1, ChronoUnit.DAYS);
Duration minusDays = duration.minusDays(1);
Duration minusHours = duration.minusHours(1);
Duration minusMinutes = duration.minusMinutes(1);
Duration minusSeconds = duration.minusSeconds(1);
Duration minusMillis = duration.minusMillis(1);
Duration minusNanos = duration.minusNanos(1);
其实minus方法调用的plus方法,如图
Period常用方法
Period period = Period.between(LocalDate.of(2022, 2, 2),
LocalDate.of(2023, 3, 3));
int years = period.getYears();
int months = period.getMonths();
int days = period.getDays();
Period plus = period.plus(Period.of(1, 1, 1));
Period plusYears = period.plusYears(1);
Period plusMonths = period.plusMonths(1);
Period plusDays = period.plusDays(1);
Period minus = period.minus(Period.of(1, 1, 1));
Period period3 = period.minusYears(1);
Period minusMonths = period.minusMonths(1);
Period minusDays = period.minusDays(1);
同样的minus也是调用plus