Module java.base

Interface Temporal

所有超级接口:
TemporalAccessor
所有已知子接口:
ChronoLocalDate, ChronoLocalDateTime<D>, ChronoZonedDateTime<D>
所有已知实现类:
HijrahDate, Instant, JapaneseDate, LocalDate, LocalDateTime, LocalTime, MinguoDate, OffsetDateTime, OffsetTime, ThaiBuddhistDate, Year, YearMonth, ZonedDateTime

public interface Temporal extends TemporalAccessor
框架级接口,定义对时间对象(如日期、时间、偏移或这些组合)的读写访问。

这是日期、时间和偏移对象的基本接口类型,这些对象足够完整,可以使用加法和减法进行操作。它由那些可以提供和操作信息作为字段查询的类实现。请参阅TemporalAccessor以获取此接口的只读版本。

大多数日期和时间信息可以表示为数字。这些使用TemporalField进行建模,使用long保存数字以处理大值。年、月和日是字段的简单示例,但它们还包括瞬时和偏移。请参阅ChronoField以获取标准字段集。

两个日期/时间信息无法用数字表示,即年表时区。可以通过使用定义在TemporalQuery上的静态方法的查询来访问这些信息。

此接口是一个框架级接口,不应在应用程序代码中广泛使用。相反,应用程序应创建并传递具体类型的实例,例如LocalDate。这样做的许多原因之一是,此接口的实现可能在ISO之外的日历系统中。请参阅ChronoLocalDate以获取有关这些问题的更全面讨论。

何时实现

如果一个类满足以下三个条件,则应实现此接口:

  • 它提供对日期/时间/偏移信息的访问,如TemporalAccessor
  • 字段集从最大到最小是连续的
  • 字段集是完整的,不需要其他字段来定义所表示字段的有效值范围

四个示例可以清楚地说明这一点:

  • LocalDate实现了此接口,因为它表示的字段集从天到永远是连续的,并且不需要外部信息来确定每个日期的有效性。因此,它能够正确实现加法/减法。
  • LocalTime实现了此接口,因为它表示的字段集从纳秒到天内是连续的,并且不需要外部信息来确定有效性。它能够通过在一天内循环来正确实现加法/减法。
  • MonthDay,即年月和日的组合,不实现此接口。虽然组合是连续的,从天到年内的月份,但组合没有足够的信息来定义日的有效值范围。因此,它无法正确实现加法/减法。
  • 星期几和日期的组合(“星期五13日”)不应实现此接口。它不表示连续的字段集,因为天到周重叠了天到月。
实现要求:
此接口不对实现的可变性施加任何限制,但强烈建议使用不可变性。所有实现必须是Comparable的。
自:
1.8
  • Method Details

    • isSupported

      boolean isSupported(TemporalUnit unit)
      检查指定的单位是否受支持。

      这将检查指定的单位是否可以添加到此日期时间中,如果为false,则调用plus(long, TemporalUnit)minus方法将抛出异常。

      实现要求:
      实现必须检查和处理ChronoUnit中定义的所有单位。如果支持该单位,则必须返回true,否则必须返回false。

      如果字段不是ChronoUnit,则通过调用TemporalUnit.isSupportedBy(Temporal)并将this作为参数来获取此方法的结果。

      实现必须确保在调用此只读方法时不会更改任何可观察状态。

      参数:
      unit - 要检查的单位,null返回false
      返回:
      如果单位可以添加/减去,则为true,否则为false
    • with

      default Temporal with(TemporalAdjuster adjuster)
      返回进行调整后的与此对象相同类型的对象。

      根据指定调整器的规则调整此日期时间。简单的调整器可能只是设置一个字段,例如年字段。更复杂的调整器可能将日期设置为该月的最后一天。在TemporalAdjusters中提供了一些常见的调整选项。这些包括查找“月末”和“下周三”。调整器负责处理特殊情况,例如月份的长度和闰年。

      以下是一些示例代码,说明了为什么以及如何使用此方法:

        date = date.with(Month.JULY);        // 大多数关键类实现了TemporalAdjuster
        date = date.with(lastDayOfMonth());  // 从Adjusters进行静态导入
        date = date.with(next(WEDNESDAY));   // 从Adjusters和DayOfWeek进行静态导入
       
      实现要求:

      实现不得更改此对象或指定的时间对象。相反,必须返回原始对象的调整副本。这为不可变和可变实现提供了等效的安全行为。

      默认实现必须等效于以下代码:

        return adjuster.adjustInto(this);
       
      参数:
      adjuster - 要使用的调整器,非null
      返回:
      具有指定调整的相同类型的对象,非null
      抛出:
      DateTimeException - 如果无法进行调整
      ArithmeticException - 如果发生数值溢出
    • with

      Temporal with(TemporalField field, long newValue)
      返回更改指定字段后与此对象相同类型的对象。

      根据此对象创建一个新对象,其中指定字段的值已更改。例如,在LocalDate上,可以使用此方法设置年、月或日。返回的对象将具有与此对象相同的可观察类型。

      在某些情况下,更改字段的定义不完全。例如,如果目标对象是代表1月31日的日期,则将月份更改为2月将是不明确的。在这种情况下,字段负责解析结果。通常,它将选择前一个有效日期,例如在此示例中为2月的最后一个有效日期。

      实现要求:
      实现必须检查和处理ChronoField中定义的所有字段。如果支持该字段,则必须执行调整。如果不支持,则必须抛出UnsupportedTemporalTypeException

      如果字段不是ChronoField,则通过调用TemporalField.adjustInto(Temporal, long)并将this作为第一个参数来获取此方法的结果。

      实现不得更改此对象。而是必须返回原始对象的调整副本。这为不可变和可变实现提供了等效且安全的行为。

      参数:
      field - 要在结果中设置的字段,不能为空
      newValue - 结果中字段的新值
      返回:
      具有指定字段设置的相同类型的对象,不能为空
      抛出:
      DateTimeException - 如果无法设置字段
      UnsupportedTemporalTypeException - 如果不支持该字段
      ArithmeticException - 如果发生数值溢出
    • plus

      default Temporal plus(TemporalAmount amount)
      返回一个与此对象相同类型的对象,其中添加了一定数量的对象。

      这会调整此时间对象,根据指定数量的规则进行添加。数量通常是一个Period,但也可以是实现TemporalAmount接口的任何其他类型,例如Duration

      以下是指示如何以及为何使用此方法的一些示例代码:

        date = date.plus(period);                // 添加一个Period实例
        date = date.plus(duration);              // 添加一个Duration实例
        date = date.plus(workingDays(6));        // 示例用户编写的workingDays方法
       

      请注意,调用plus后跟minus不能保证返回相同的日期时间。

      实现要求:

      实现不得更改此对象或指定的时间对象。而是必须返回原始对象的调整副本。这为不可变和可变实现提供了等效且安全的行为。

      默认实现必须等效于以下代码:

        return amount.addTo(this);
       
      参数:
      amount - 要添加的数量,不能为空
      返回:
      具有指定调整的相同类型的对象,不能为空
      抛出:
      DateTimeException - 如果无法进行添加
      ArithmeticException - 如果发生数值溢出
    • plus

      Temporal plus(long amountToAdd, TemporalUnit unit)
      返回一个与此对象相同类型的对象,其中添加了指定的周期。

      此方法返回一个基于此对象的新对象,其中添加了指定的周期。例如,在LocalDate上,可以用来添加一定数量的年、月或日。返回的对象将具有与此对象相同的可观察类型。

      在某些情况下,更改字段的定义不完全明确。例如,如果目标对象是代表1月31日的日期,则添加一个月将是不明确的。在这种情况下,字段负责解析结果。通常它会选择前一个有效日期,例如在此示例中将是2月的最后一个有效日期。

      实现要求:
      实现必须检查和处理ChronoUnit中定义的所有单位。如果支持该单位,则必须执行添加操作。如果不支持,则必须抛出UnsupportedTemporalTypeException

      如果单位不是ChronoUnit,则通过调用TemporalUnit.addTo(Temporal, long)并将this作为第一个参数来获取此方法的结果。

      实现不得更改此对象。而是必须返回原始对象的调整副本。这为不可变和可变实现提供了等效且安全的行为。

      参数:
      amountToAdd - 要添加的指定单位的数量,可以为负数
      unit - 要添加数量的单位,不能为空
      返回:
      具有指定周期添加的相同类型的对象,不能为空
      抛出:
      DateTimeException - 如果无法添加单位
      UnsupportedTemporalTypeException - 如果不支持该单位
      ArithmeticException - 如果发生数值溢出
    • minus

      default Temporal minus(TemporalAmount amount)
      返回一个与此对象相同类型的对象,其中减去了一定数量的对象。

      这会调整此时间对象,根据指定数量的规则进行减法。数量通常是一个Period,但也可以是实现TemporalAmount接口的任何其他类型,例如Duration

      以下是指示如何以及为何使用此方法的一些示例代码:

        date = date.minus(period);               // 减去一个Period实例
        date = date.minus(duration);             // 减去一个Duration实例
        date = date.minus(workingDays(6));       // 示例用户编写的workingDays方法
       

      请注意,调用plus后跟minus不能保证返回相同的日期时间。

      实现要求:

      实现不得更改此对象或指定的时间对象。而是必须返回原始对象的调整副本。这为不可变和可变实现提供了等效且安全的行为。

      默认实现必须等效于以下代码:

        return amount.subtractFrom(this);
       
      参数:
      amount - 要减去的数量,不能为空
      返回:
      具有指定调整的相同类型的对象,不能为空
      抛出:
      DateTimeException - 如果无法进行减法
      ArithmeticException - 如果发生数值溢出
    • minus

      default Temporal minus(long amountToSubtract, TemporalUnit unit)
      返回一个与此对象相同类型的对象,其中减去了指定的周期。

      此方法返回一个基于此对象的新对象,其中减去了指定的周期。例如,在LocalDate上,可以用来减去一定数量的年、月或日。返回的对象将具有与此对象相同的可观察类型。

      在某些情况下,更改字段的定义不完全明确。例如,如果目标对象是代表3月31日的日期,则减去一个月将是不明确的。在这种情况下,字段负责解析结果。通常它会选择前一个有效日期,例如在此示例中将是2月的最后一个有效日期。

      实现要求:
      实现必须表现为等效于默认方法行为。

      实现不得更改此对象。而是必须返回原始对象的调整副本。这为不可变和可变实现提供了等效且安全的行为。

      默认实现必须等效于以下代码:

        return (amountToSubtract == Long.MIN_VALUE ?
            plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit));
       
      参数:
      amountToSubtract - 要减去的指定单位的数量,可以为负数
      unit - 要减去数量的单位,不能为空
      返回:
      具有指定周期减去的相同类型的对象,不能为空
      抛出:
      DateTimeException - 如果无法减去单位
      UnsupportedTemporalTypeException - 如果不支持该单位
      ArithmeticException - 如果发生数值溢出
    • until

      long until(Temporal endExclusive, TemporalUnit unit)
      计算到另一个时间对象之间的时间量,以指定单位表示。

      这会计算两个时间对象之间的时间量,以单个TemporalUnit表示。起始点和结束点分别为this和指定的时间对象。如果不同,则将结束点转换为与起始点相同的类型。如果结束在起始之前,则结果将为负数。例如,可以使用startTime.until(endTime, HOURS)来计算两个时间对象之间的小时数。

      计算返回一个整数,表示两个时间之间完整单位的数量。例如,在11:30和13:29之间的小时数只有一个小时,因为它距离两个小时仅有一分钟。

      有两种等效的使用此方法的方式。第一种是直接调用此方法。第二种是使用TemporalUnit.between(Temporal, Temporal):

         // 这两行代码是等效的
         temporal = start.until(end, unit);
         temporal = unit.between(start, end);
       
      应根据哪种方式使代码更易读来进行选择。

      例如,此方法允许计算两个日期之间的天数:

        long daysBetween = start.until(end, DAYS);
        // 或者
        long daysBetween = DAYS.between(start, end);
       
      实现要求:
      实现必须首先检查输入的时间对象是否与实现的可观察类型相同。然后,它们必须对所有ChronoUnit的实例执行计算。对于不支持的ChronoUnit实例,必须抛出UnsupportedTemporalTypeException异常。

      如果单位不是ChronoUnit,则通过调用TemporalUnit.between(Temporal, Temporal)方法,将this作为第一个参数,转换后的输入时间作为第二个参数来获取此方法的结果。

      总之,实现必须表现为等效于以下伪代码:

        // 将结束时间转换为与此类相同的类型
        if (unit instanceof ChronoUnit) {
          // 如果单位受支持,则计算并返回结果
          // 否则,对于不受支持的单位,抛出UnsupportedTemporalTypeException
        }
        return unit.between(this, convertedEndTemporal);
       

      请注意,只有当两个时间对象通过getClass()评估具有完全相同的类型时,才会调用单位的between方法。

      在调用此只读方法时,实现必须确保不会更改任何可观察状态。

      参数:
      endExclusive - 结束时间(不包括),转换为与此对象相同类型,不能为空
      unit - 用于测量数量的单位,不能为空
      返回值:
      以单位为基础计算此时间对象与指定时间对象之间的时间量;如果指定对象晚于此对象,则为正,如果早于此对象,则为负
      抛出:
      DateTimeException - 如果无法计算数量,或者无法将结束时间转换为与此时间对象相同的类型
      UnsupportedTemporalTypeException - 如果单位不受支持
      ArithmeticException - 如果发生数值溢出