public interface ChronoLocalDate extends Temporal, TemporalAdjuster, Comparable<ChronoLocalDate>
大多数应用程序应声明方法签名,字段和变量为LocalDate
,而不是此接口。
A ChronoLocalDate
是Chronology chronology
或日历系统可插拔的日期的抽象表示。 日期由TemporalField
表示的字段定义,其中大多数常见实现在ChronoField
中定义。 年表定义日历系统的运行方式和标准字段的含义。
LocalDate
而不是该接口,即使在应用程序需要处理多个日历系统的情况下。
在以下文档中探讨了其理由。
应该使用此接口的主要用例是通用类型参数<D>
完全定义为特定年表。 在这种情况下,这个年表的假设在开发时是已知的,并在代码中指定。
当时间顺序在通用类型参数中定义为? 或在开发时以其他方式未知,下面讨论的其余部分适用。
为了强调这一点,声明一个方法签名,字段或变量作为这个接口类型最初似乎是一个全局化应用程序的合理方式,但通常是错误的方法。 因此,与LocalDate相反,它应该被认为是应用程序范围的架构决定来选择使用此LocalDate
。
1)使用这个界面的应用程序,而不是仅使用LocalDate
,面临着更高的错误概率。 这是因为正在使用的日历系统在开发时不知道。 错误的主要原因是开发人员将ISO日历系统日常知识的假设应用于旨在处理任意日历系统的代码。 以下部分概述了这些假设如何导致问题。减少错误风险增加的主要机制是强大的代码审查流程。 在代码生命周期中,这也应被视为维护的额外成本。
2)此接口不强制执行不可变性。 虽然实现说明表明所有实现都必须是不可变的,但代码或类型系统中没有任何内容来执行此操作。 因此,声明接受ChronoLocalDate
任何方法可能会被传递给恶意或恶意的可变实现。
3)使用此界面的应用程序必须考虑到时代的影响。 LocalDate
屏蔽用户的时代概念,通过确保getYear()
返回光明年。 该决定确保开发人员可以将LocalDate
实例视为三个字段(年,月,日和月)。 相比之下,这个界面的用户必须将日期视为由四个领域组成的 - 时代,年龄,月份和月份。 额外的时代领域经常被遗忘,但是在任意的日历系统中是至关重要的。 例如,在日历系统中,这个时代代表了皇帝的统治地位。 每当一个统治结束,另一个开始时,年龄将重置为一个。
4)在两个系统之间通过日期的唯一商定的国际标准是需要ISO日历系统的ISO-8601标准。 在整个应用程序中使用此界面将不可避免地导致要求通过网络或组件边界传递日期,需要特定于应用程序的协议或格式。
5)长期持续性,如数据库,几乎总是只接受ISO-8601日历系统(或相关的朱利安 - 格里高利)的日期。 在其他日历系统中传播日期增加了与持久性相互作用的并发症。
6)大部分时间,通过一个ChronoLocalDate
程序ChronoLocalDate是不必要的,如下面最后一节所讨论的。
查询月份的代码,并假定该值永远不会超过31,则无效。 某些日历系统在几个月内有超过31天的时间。
增加12个月的代码,并假设已经添加了一年是无效的。 一些日历系统有不同的月份,例如科普特人或埃塞俄比亚的13个。
增加一个月到日期的代码,并假设年月值增加一个或换到下一年是无效的。 一些日历系统在一年中可能有几个月,例如希伯来语。
增加一个月的代码,然后再增加一个月,并假设月日将保持接近其原始值是无效的。 一些日历系统在最长月份的长度和最短的月份的长度之间有很大差异。 例如,科普特人或埃塞俄比亚人有12个月30天,1个月5天。
添加七天并假定一周已添加的代码无效。 一些日历系统有七个星期的时间,如法国革命派。
代码假设因为date1
的年份大于date2
年,那么date1
之后是date2
无效。 对于所有的日历系统来说,这是对年龄的无效的,尤其是日后的日历系统,这个日历系统在每个新皇帝的统治时期重新启动。
将月份中的一个月和一个月中的一个作为年初的代码无效。 当月份值为1时,不是所有的日历系统开始。
一般来说,操作日期,甚至查询日期,当日历系统在开发时是未知的时,广泛使用错误。 这就是为什么使用此界面的代码必须经过其他代码审查的原因。 这也是为什么避免这种接口类型的架构决策通常是正确的。
LocalDate
。 LocalDate
转换为用户首选日历系统 如上所述,在日历系统的规则可插拔的日期执行计算需要技能,不推荐。 幸运的是,在任意日历系统的日期执行计算的需求是极少数的。 例如,图书馆租借计划的商业规则极不可能允许租金为一个月,其中月份的含义取决于用户的首选日历系统。
在任意日历系统中的日期计算的关键用例是生成逐月显示和用户交互的日历。 再次,这是一个UI问题,仅仅在UI层的几个方法中使用这个接口可能是合理的。
在系统的任何其他部分,如果在除ISO之外的日历系统中必须操作日期,则用例通常会指定要使用的日历系统。 例如,申请可能需要计算下一个可能需要操纵日期的伊斯兰教或希伯来节假日。 这种用例可以如下处理:
LocalDate
开始传递给该方法 LocalDate
TemporalAccessor
如果需要只读访问,或使用Temporal
是否需要进行读写访问。
可以向系统添加其他日历系统。 详见Chronology
。
Modifier and Type | Method and Description |
---|---|
default Temporal |
adjustInto(Temporal temporal)
调整指定的时间对象与此对象的日期相同。
|
default ChronoLocalDateTime<?> |
atTime(LocalTime localTime)
结合此日期与时间创建一个
ChronoLocalDateTime 。
|
default int |
compareTo(ChronoLocalDate other)
将此日期与其他日期进行比较,包括年表。
|
boolean |
equals(Object obj)
检查这个日期是否等于另一个日期,包括年表。
|
default String |
format(DateTimeFormatter formatter)
使用指定的格式化程序格式化此日期。
|
static ChronoLocalDate |
from(TemporalAccessor temporal)
从时间对象获取一个
ChronoLocalDate 的实例。
|
Chronology |
getChronology()
获得这个日期的年表。
|
default Era |
getEra()
获得时代,按年表定义。
|
int |
hashCode()
这个日期的哈希码。
|
default boolean |
isAfter(ChronoLocalDate other)
检查此日期是否在忽略年表的指定日期之后。
|
default boolean |
isBefore(ChronoLocalDate other)
检查此日期是否在忽略年表前的指定日期之前。
|
default boolean |
isEqual(ChronoLocalDate other)
检查这个日期是否等于忽略年表的指定日期。
|
default boolean |
isLeapYear()
检查年份是否是日历系统定义的闰年。
|
default boolean |
isSupported(TemporalField field)
检查指定的字段是否受支持。
|
default boolean |
isSupported(TemporalUnit unit)
检查指定的单位是否受支持。
|
int |
lengthOfMonth()
返回由日历系统定义的由此日期表示的月份的长度。
|
default int |
lengthOfYear()
返回由日历系统定义的由此日期表示的年份的长度。
|
default ChronoLocalDate |
minus(long amountToSubtract, TemporalUnit unit)
返回与该对象相同类型的对象,并减去指定的时间段。
|
default ChronoLocalDate |
minus(TemporalAmount amount)
返回与该对象相同类型的对象,并减去一个数量。
|
default ChronoLocalDate |
plus(long amountToAdd, TemporalUnit unit)
返回与此对象相同类型的对象,并添加指定的句点。
|
default ChronoLocalDate |
plus(TemporalAmount amount)
返回与此对象相同类型的对象,并添加一个金额。
|
default <R> R |
query(TemporalQuery<R> query)
使用指定的查询查询此日期。
|
static Comparator<ChronoLocalDate> |
timeLineOrder()
获取一个比较器,比较
ChronoLocalDate 的时间顺序忽略年表。
|
default long |
toEpochDay()
将此日期转换为大纪元日。
|
String |
toString()
将此日期输出为
String 。
|
ChronoPeriod |
until(ChronoLocalDate endDateExclusive)
将此日期和另一个日期之间的期间计算为
ChronoPeriod 。
|
long |
until(Temporal endExclusive, TemporalUnit unit)
根据指定的单位计算直到另一个日期的时间量。
|
default ChronoLocalDate |
with(TemporalAdjuster adjuster)
通过进行调整,返回与该对象相同类型的调整对象。
|
default ChronoLocalDate |
with(TemporalField field, long newValue)
返回与该对象具有相同类型的对象,并更改指定的字段。
|
get, getLong, range
static Comparator<ChronoLocalDate> timeLineOrder()
ChronoLocalDate
在时间顺序忽略年表。
这个比较器的不同之处的比较compareTo(java.time.chrono.ChronoLocalDate)
在于其只比较基础日期和不年表。 这可以根据当地时间线上日期的位置来比较不同日历系统中的日期。 潜在的比较相当于比较时代。
static ChronoLocalDate from(TemporalAccessor temporal)
ChronoLocalDate
的实例。
这将基于指定的时间获取本地日期。 A TemporalAccessor
代表日期和时间信息的任意集合,该工厂将其转换为ChronoLocalDate
一个实例。
转换提取并结合时间对象的年表和日期。 该行为相当于使用Chronology.date(TemporalAccessor)
与提取的年表。 允许实现执行优化,例如访问与相关对象相当的那些字段。
该方法中,功能接口的签名相匹配TemporalQuery
允许它被用作通过方法参考,查询ChronoLocalDate::from
。
temporal
- 要转换的时间对象,不为null
DateTimeException
- 如果无法转换为
ChronoLocalDate
Chronology.date(TemporalAccessor)
Chronology getChronology()
Chronology
代表正在使用的日历系统。 ChronoField
中的时代和其他领域由年表定义。
default Era getEra()
时代在概念上是时间线上最大的一个部门。 大多数日历系统具有将时间线划分为两个时代的单个时期。 然而,有些有多个时代,比如每个领导人统治的时代。 具体含义由Chronology
。
所有正确实现的Era
类都是单例,因此它是写有效的代码date.getEra() == SomeChrono.ERA_NAME)
。
此默认实现使用Chronology.eraOf(int)
。
default boolean isLeapYear()
闰年是一个比正常长的一年。 确切的意义是由年表确定的,其限制是闰年必须意味着比非闰年长一年的长度。
此默认实现使用Chronology.isLeapYear(long)
。
int lengthOfMonth()
这将以天为单位返回月份的长度。
default int lengthOfYear()
default boolean isSupported(TemporalField field)
这将检查是否可以在此日期查询指定的字段。 如果是假,然后调用range
, get
和with(TemporalField, long)
方法会抛出异常。
一组支持的字段由年表定义,通常包括所有ChronoField
日期字段。
如果该字段不是ChronoField
,则该方法的结果是通过调用TemporalField.isSupportedBy(TemporalAccessor)
通过this
作为参数获得的。 字段是否受支持由字段决定。
isSupported
在界面
TemporalAccessor
field
- 要检查的字段,null返回false
default boolean isSupported(TemporalUnit unit)
这将检查是否可以从该日期添加或减去指定的单位。 如果是false,那么调用plus(long, TemporalUnit)
和minus
方法会抛出异常。
支持单位的集合由年表定义,通常包括除FOREVER
之外的所有ChronoUnit
日期单位。
如果该单元不是ChronoUnit
,则此方法的结果是通过调用获得TemporalUnit.isSupportedBy(Temporal)
传递this
作为参数。 设备是否受支持由本机决定。
isSupported
在界面
Temporal
unit
- 要检查的单位,null返回false
default ChronoLocalDate with(TemporalAdjuster adjuster)
这将根据指定的调整器的规则调整此日期时间。 一个简单的调整器可能只是设置一个字段,如年份字段。 更复杂的调整器可能会将日期设置为该月的最后一天。 TemporalAdjuster
提供了一些常见的调整 。 这些包括找到“月的最后一天”和“下周三”。 调整员负责处理特殊情况,如月份和闰年的不同长度。
一些示例代码,指示如何和为什么使用此方法:
date = date.with(Month.JULY); // most key classes implement TemporalAdjuster
date = date.with(lastDayOfMonth()); // static import from Adjusters
date = date.with(next(WEDNESDAY)); // static import from Adjusters and DayOfWeek
with
在界面
Temporal
adjuster
- 调整器使用,不为空
DateTimeException
- 如果不能进行调整
ArithmeticException
- 如果发生数字溢出
default ChronoLocalDate with(TemporalField field, long newValue)
这将返回一个基于该对象的新对象,其中指定字段的值已更改。 例如,在LocalDate
,这可以用于设置年,月或月的日期。 返回的对象将具有与该对象相同的可观察类型。
在某些情况下,更改字段尚未完全定义。 例如,如果目标对象是代表1月31日的日期,则将月份更改为2月份将不清楚。 在这种情况下,该领域负责解决结果。 通常,它将选择先前的有效日期,这将是本例中最后一个有效的二月份。
with
在界面
Temporal
field
- 要在结果中设置的字段,不为null
newValue
- 结果中字段的新值
DateTimeException
- 如果该字段无法设置
UnsupportedTemporalTypeException
- 如果该字段不被支持
ArithmeticException
- 如果发生数字溢出
default ChronoLocalDate plus(TemporalAmount amount)
这调整这个时间,根据指定量的规则添加。 金额一般为Period
,但可能是实现TemporalAmount
界面的任何其他类型,如Duration
。
一些示例代码,指示如何和为什么使用此方法:
date = date.plus(period); // add a Period instance
date = date.plus(duration); // add a Duration instance
date = date.plus(workingDays(6)); // example user-written workingDays method
请注意,呼叫plus
后跟minus
不保证返回相同的日期时间。
plus
在界面
Temporal
amount
- 要添加的金额,不为null
DateTimeException
- 如果不能添加
ArithmeticException
- 如果发生数字溢出
default ChronoLocalDate plus(long amountToAdd, TemporalUnit unit)
此方法基于添加了指定句点的新对象。 例如,在LocalDate
,这可以用来添加几年,几个月或几天。 返回的对象将具有与该对象相同的可观察类型。
在某些情况下,更改字段尚未完全定义。 例如,如果目标对象是代表1月31日的日期,则添加一个月将不清楚。 在这种情况下,该领域负责解决结果。 通常,它将选择先前的有效日期,这将是本例中最后一个有效的二月份。
plus
在接口
Temporal
amountToAdd
- 要添加的指定单位的数量,可能为负数
unit
- 要添加的单位,不为空
DateTimeException
- 如果无法添加本机
ArithmeticException
- 如果发生数字溢出
default ChronoLocalDate minus(TemporalAmount amount)
这调整这个时间,根据指定量的规则减去。 量通常为Period
,而可以是任何其他类型的实现TemporalAmount
接口,如Duration
。
一些示例代码,指示如何和为什么使用此方法:
date = date.minus(period); // subtract a Period instance
date = date.minus(duration); // subtract a Duration instance
date = date.minus(workingDays(6)); // example user-written workingDays method
请注意,呼叫plus
后跟minus
不保证返回相同的日期时间。
minus
在接口
Temporal
amount
- 减去量,不为空
DateTimeException
- 如果不能进行减法
ArithmeticException
- 如果发生数字溢出
default ChronoLocalDate minus(long amountToSubtract, TemporalUnit unit)
该方法返回一个基于该对象的新对象,减去指定的时间段。 例如,在LocalDate
,这可以用来减去几年,几个月或几天。 返回的对象将具有与该对象相同的可观察类型。
在某些情况下,更改字段尚未完全定义。 例如,如果目标对象是代表3月31日的日期,则减去一个月将不清楚。 在这种情况下,该领域负责解决结果。 通常,它将选择先前的有效日期,这将是本例中最后一个有效的二月份。
minus
中的
Temporal
amountToSubtract
- 减去指定单位的金额,可能为负数
unit
- 减去期间的单位,不为空
DateTimeException
- 如果不能减去单位
UnsupportedTemporalTypeException
- 如果不支持本机
ArithmeticException
- 如果发生数字溢出
default <R> R query(TemporalQuery<R> query)
这使用指定的查询策略对象查询此日期。 TemporalQuery
对象定义了用于获取结果的逻辑。 阅读查询的文档,以了解该方法的结果。
该方法的结果是通过在指定的查询this
作为参数调用TemporalQuery.queryFrom(TemporalAccessor)
方法获得的。
query
在接口
TemporalAccessor
R
- 结果的类型
query
- 要调用的查询,不为空
DateTimeException
- 如果无法查询(由查询定义)
ArithmeticException
- 如果发生数字溢出(由查询定义)
default Temporal adjustInto(Temporal temporal)
这返回与日期改变为与之相同的输入的相同可观察类型的时间对象。
该调整是相当于使用Temporal.with(TemporalField, long)
传递ChronoField.EPOCH_DAY
作为字段。
在大多数情况下,通过使用Temporal.with(TemporalAdjuster)
来更正调用模式:
// these two lines are equivalent, but the second approach is recommended
temporal = thisLocalDate.adjustInto(temporal);
temporal = temporal.with(thisLocalDate);
此实例是不可变的,不受此方法调用的影响。
adjustInto
在界面
TemporalAdjuster
temporal
- 要调整的目标对象,不为null
DateTimeException
- 如果不能进行调整
ArithmeticException
- 如果发生数字溢出
long until(Temporal endExclusive, TemporalUnit unit)
这样可以计算两个ChronoLocalDate
对象之间的时间ChronoLocalDate
,单位为TemporalUnit
。 起点和终点是this
和指定的日期。 如果结束在开始之前,结果将为负数。 所述Temporal
传递给此方法被转换为ChronoLocalDate
使用Chronology.date(TemporalAccessor)
。 计算返回一个整数,表示两个日期之间的完整单位数。 例如,可以使用startDate.until(endDate, DAYS)
两个日期之间的天数。
使用这种方法有两种等效的方法。 第一个是调用这个方法。 二是使用TemporalUnit.between(Temporal, Temporal)
:
// these two lines are equivalent
amount = start.until(end, MONTHS);
amount = MONTHS.between(start, end);
应该根据这种做法进行选择,使代码更易读。
计算在ChronoUnit
的这种方法中实现 。 单位DAYS
, WEEKS
, MONTHS
, YEARS
, DECADES
, CENTURIES
, MILLENNIA
和ERAS
应该由所有的实现支持。 其他ChronoUnit
值会抛出异常。
如果该单元不是ChronoUnit
,则此方法的结果是通过调用获得TemporalUnit.between(Temporal, Temporal)
传递this
作为第一个参数和转换后的输入时间作为第二个参数。
此实例是不可变的,不受此方法调用的影响。
until
在接口
Temporal
endExclusive
-结束日期,排他的,其被转换为
ChronoLocalDate
在相同的时间顺序,而不是空
unit
- 衡量金额的单位,不为空
DateTimeException
- 如果不能计算金额,或者结束时间不能转换为
ChronoLocalDate
UnsupportedTemporalTypeException
- 如果不支持本机
ArithmeticException
- 如果发生数字溢出
ChronoPeriod until(ChronoLocalDate endDateExclusive)
ChronoPeriod
。
这计算两个日期之间的期间。 所有提供的年表使用年,月和日计算周期,但是ChronoPeriod
API允许使用其他单位来表示期间。
起点和终点是this
和指定的日期。 如果结束在开始之前,结果将为负数。 每年,每月的负号将相同。
计算使用此日期的年表进行。 如有必要,输入日期将被转换为匹配。
此实例是不可变的,不受此方法调用的影响。
endDateExclusive
- 结束日期,排他,可能在任何年代,不为空
DateTimeException
- 如果期间无法计算
ArithmeticException
- 如果发生数字溢出
default String format(DateTimeFormatter formatter)
此日期将传递给格式化程序以生成一个字符串。
默认实现必须如下所示:
return formatter.format(this);
formatter
- 格式化程序使用,不为null
DateTimeException
- 打印时是否发生错误
default ChronoLocalDateTime<?> atTime(LocalTime localTime)
ChronoLocalDateTime
。
这将返回一个ChronoLocalDateTime
从该日起在指定的时间形成的。 日期和时间的所有可能的组合都是有效的。
localTime
- 本地使用时间,不为空
default long toEpochDay()
Epoch Day count
是第0天为1970-01-01(ISO)的简单递增计数。 这个定义对于所有的年表都是一样的,可以进行转换。
此默认实现查询EPOCH_DAY
字段。
default int compareTo(ChronoLocalDate other)
比较首先是基于时间线日期,然后是时间顺序。 它与“等于”一致,如Comparable
所定义。
例如,以下是比较器顺序:
2012-12-03 (ISO)
2012-12-04 (ISO)
2555-12-04 (ThaiBuddhist)
2012-12-05 (ISO)
如果所有被比较的日期对象都在相同的年表中,则不需要额外的时间顺序,只使用本地日期。 要比较两个TemporalAccessor
实例的日期,包括两个TemporalAccessor
年表中的日期,请使用ChronoField.EPOCH_DAY
作为比较。
此默认实现执行上面定义的比较。
compareTo
在界面
Comparable<ChronoLocalDate>
other
- 要比较的其他日期,不为空
default boolean isAfter(ChronoLocalDate other)
此方法不同于在比较compareTo(java.time.chrono.ChronoLocalDate)
在于其只比较基础日期和不年表。 这允许根据时间线位置来比较不同日历系统中的日期。 这相当于使用date1.toEpochDay() > date2.toEpochDay()
。
此默认实现基于时间段执行比较。
other
- 要比较的其他日期,不为空
default boolean isBefore(ChronoLocalDate other)
此方法不同于在比较compareTo(java.time.chrono.ChronoLocalDate)
在于其只比较基础日期和不年表。 这允许根据时间线位置来比较不同日历系统中的日期。 这相当于使用date1.toEpochDay() < date2.toEpochDay()
。
此默认实现基于时间段执行比较。
other
- 要比较的其他日期,不为空
default boolean isEqual(ChronoLocalDate other)
此方法不同于在比较compareTo(java.time.chrono.ChronoLocalDate)
在于其只比较基础日期和不年表。 这允许根据时间线位置来比较不同日历系统中的日期。 这相当于使用date1.toEpochDay() == date2.toEpochDay()
。
此默认实现基于时间段执行比较。
other
- 要比较的其他日期,不为null
boolean equals(Object obj)
将此日期与另一个日期进行比较,确保日期和年表相同。
要比较两个TemporalAccessor
实例的日期,包括两个TemporalAccessor
年代的日期,请使用ChronoField.EPOCH_DAY
作为比较。
equals
在类别
Object
obj
- 要检查的对象,null返回false
Object.hashCode()
, HashMap
int hashCode()
hashCode
在类别
Object
Object.equals(java.lang.Object)
,
System.identityHashCode(java.lang.Object)