src/share/classes/java/time/chrono/ChronoLocalDate.java
Print this page
*** 240,254 ****
* Subclasses should be Serializable wherever possible.
* <p>
* Additional calendar systems may be added to the system.
* See {@link Chronology} for more details.
*
- * @param <D> the concrete type for the date
* @since 1.8
*/
! public interface ChronoLocalDate<D extends ChronoLocalDate<D>>
! extends Temporal, TemporalAdjuster, Comparable<ChronoLocalDate<?>> {
/**
* Gets a comparator that compares {@code ChronoLocalDate} in
* time-line order ignoring the chronology.
* <p>
--- 240,253 ----
* Subclasses should be Serializable wherever possible.
* <p>
* Additional calendar systems may be added to the system.
* See {@link Chronology} for more details.
*
* @since 1.8
*/
! public interface ChronoLocalDate
! extends Temporal, TemporalAdjuster, Comparable<ChronoLocalDate> {
/**
* Gets a comparator that compares {@code ChronoLocalDate} in
* time-line order ignoring the chronology.
* <p>
*** 261,271 ****
*
* @see #isAfter
* @see #isBefore
* @see #isEqual
*/
! static Comparator<ChronoLocalDate<?>> timeLineOrder() {
return Chronology.DATE_ORDER;
}
//-----------------------------------------------------------------------
/**
--- 260,270 ----
*
* @see #isAfter
* @see #isBefore
* @see #isEqual
*/
! static Comparator<ChronoLocalDate> timeLineOrder() {
return Chronology.DATE_ORDER;
}
//-----------------------------------------------------------------------
/**
*** 287,299 ****
* @param temporal the temporal object to convert, not null
* @return the date, not null
* @throws DateTimeException if unable to convert to a {@code ChronoLocalDate}
* @see Chronology#date(TemporalAccessor)
*/
! static ChronoLocalDate<?> from(TemporalAccessor temporal) {
if (temporal instanceof ChronoLocalDate) {
! return (ChronoLocalDate<?>) temporal;
}
Chronology chrono = temporal.query(TemporalQuery.chronology());
if (chrono == null) {
throw new DateTimeException("Unable to obtain ChronoLocalDate from TemporalAccessor: " + temporal.getClass());
}
--- 286,298 ----
* @param temporal the temporal object to convert, not null
* @return the date, not null
* @throws DateTimeException if unable to convert to a {@code ChronoLocalDate}
* @see Chronology#date(TemporalAccessor)
*/
! static ChronoLocalDate from(TemporalAccessor temporal) {
if (temporal instanceof ChronoLocalDate) {
! return (ChronoLocalDate) temporal;
}
Chronology chrono = temporal.query(TemporalQuery.chronology());
if (chrono == null) {
throw new DateTimeException("Unable to obtain ChronoLocalDate from TemporalAccessor: " + temporal.getClass());
}
*** 365,450 ****
*/
default int lengthOfYear() {
return (isLeapYear() ? 366 : 365);
}
@Override
default boolean isSupported(TemporalField field) {
if (field instanceof ChronoField) {
return field.isDateBased();
}
return field != null && field.isSupportedBy(this);
}
//-----------------------------------------------------------------------
// override for covariant return type
/**
* {@inheritDoc}
* @throws DateTimeException {@inheritDoc}
* @throws ArithmeticException {@inheritDoc}
*/
@Override
! default D with(TemporalAdjuster adjuster) {
! return (D) getChronology().ensureChronoLocalDate(Temporal.super.with(adjuster));
}
/**
* {@inheritDoc}
* @throws DateTimeException {@inheritDoc}
* @throws UnsupportedTemporalTypeException {@inheritDoc}
* @throws ArithmeticException {@inheritDoc}
*/
@Override
! default D with(TemporalField field, long newValue) {
if (field instanceof ChronoField) {
! throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName());
}
! return (D) getChronology().ensureChronoLocalDate(field.adjustInto(this, newValue));
}
/**
* {@inheritDoc}
* @throws DateTimeException {@inheritDoc}
* @throws ArithmeticException {@inheritDoc}
*/
@Override
! default D plus(TemporalAmount amount) {
! return (D) getChronology().ensureChronoLocalDate(Temporal.super.plus(amount));
}
/**
* {@inheritDoc}
* @throws DateTimeException {@inheritDoc}
* @throws ArithmeticException {@inheritDoc}
*/
@Override
! default D plus(long amountToAdd, TemporalUnit unit) {
if (unit instanceof ChronoUnit) {
! throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName());
}
! return (D) getChronology().ensureChronoLocalDate(unit.addTo(this, amountToAdd));
}
/**
* {@inheritDoc}
* @throws DateTimeException {@inheritDoc}
* @throws ArithmeticException {@inheritDoc}
*/
@Override
! default D minus(TemporalAmount amount) {
! return (D) getChronology().ensureChronoLocalDate(Temporal.super.minus(amount));
}
/**
* {@inheritDoc}
* @throws DateTimeException {@inheritDoc}
* @throws UnsupportedTemporalTypeException {@inheritDoc}
* @throws ArithmeticException {@inheritDoc}
*/
@Override
! default D minus(long amountToSubtract, TemporalUnit unit) {
! return (D) getChronology().ensureChronoLocalDate(Temporal.super.minus(amountToSubtract, unit));
}
//-----------------------------------------------------------------------
/**
* Queries this date using the specified query.
--- 364,494 ----
*/
default int lengthOfYear() {
return (isLeapYear() ? 366 : 365);
}
+ /**
+ * Checks if the specified field is supported.
+ * <p>
+ * This checks if the specified field can be queried on this date.
+ * If false, then calling the {@link #range(TemporalField) range},
+ * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)}
+ * methods will throw an exception.
+ * <p>
+ * The set of supported fields is defined by the chronology and normally includes
+ * all {@code ChronoField} date fields.
+ * <p>
+ * If the field is not a {@code ChronoField}, then the result of this method
+ * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
+ * passing {@code this} as the argument.
+ * Whether the field is supported is determined by the field.
+ *
+ * @param field the field to check, null returns false
+ * @return true if the field can be queried, false if not
+ */
@Override
default boolean isSupported(TemporalField field) {
if (field instanceof ChronoField) {
return field.isDateBased();
}
return field != null && field.isSupportedBy(this);
}
+ /**
+ * Checks if the specified unit is supported.
+ * <p>
+ * This checks if the specified unit can be added to or subtracted from this date.
+ * If false, then calling the {@link #plus(long, TemporalUnit)} and
+ * {@link #minus(long, TemporalUnit) minus} methods will throw an exception.
+ * <p>
+ * The set of supported units is defined by the chronology and normally includes
+ * all {@code ChronoUnit} date units except {@code FOREVER}.
+ * <p>
+ * If the unit is not a {@code ChronoUnit}, then the result of this method
+ * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)}
+ * passing {@code this} as the argument.
+ * Whether the unit is supported is determined by the unit.
+ *
+ * @param unit the unit to check, null returns false
+ * @return true if the unit can be added/subtracted, false if not
+ */
+ @Override
+ default boolean isSupported(TemporalUnit unit) {
+ if (unit instanceof ChronoUnit) {
+ return unit.isDateBased();
+ }
+ return unit != null && unit.isSupportedBy(this);
+ }
+
//-----------------------------------------------------------------------
// override for covariant return type
/**
* {@inheritDoc}
* @throws DateTimeException {@inheritDoc}
* @throws ArithmeticException {@inheritDoc}
*/
@Override
! default ChronoLocalDate with(TemporalAdjuster adjuster) {
! return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.with(adjuster));
}
/**
* {@inheritDoc}
* @throws DateTimeException {@inheritDoc}
* @throws UnsupportedTemporalTypeException {@inheritDoc}
* @throws ArithmeticException {@inheritDoc}
*/
@Override
! default ChronoLocalDate with(TemporalField field, long newValue) {
if (field instanceof ChronoField) {
! throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
}
! return ChronoDateImpl.ensureValid(getChronology(), field.adjustInto(this, newValue));
}
/**
* {@inheritDoc}
* @throws DateTimeException {@inheritDoc}
* @throws ArithmeticException {@inheritDoc}
*/
@Override
! default ChronoLocalDate plus(TemporalAmount amount) {
! return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.plus(amount));
}
/**
* {@inheritDoc}
* @throws DateTimeException {@inheritDoc}
* @throws ArithmeticException {@inheritDoc}
*/
@Override
! default ChronoLocalDate plus(long amountToAdd, TemporalUnit unit) {
if (unit instanceof ChronoUnit) {
! throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
}
! return ChronoDateImpl.ensureValid(getChronology(), unit.addTo(this, amountToAdd));
}
/**
* {@inheritDoc}
* @throws DateTimeException {@inheritDoc}
* @throws ArithmeticException {@inheritDoc}
*/
@Override
! default ChronoLocalDate minus(TemporalAmount amount) {
! return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.minus(amount));
}
/**
* {@inheritDoc}
* @throws DateTimeException {@inheritDoc}
* @throws UnsupportedTemporalTypeException {@inheritDoc}
* @throws ArithmeticException {@inheritDoc}
*/
@Override
! default ChronoLocalDate minus(long amountToSubtract, TemporalUnit unit) {
! return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.minus(amountToSubtract, unit));
}
//-----------------------------------------------------------------------
/**
* Queries this date using the specified query.
*** 520,537 ****
* The {@code Temporal} passed to this method must be a
* {@code ChronoLocalDate} in the same chronology.
* The calculation returns a whole number, representing the number of
* complete units between the two dates.
* For example, the amount in days between two dates can be calculated
! * using {@code startDate.periodUntil(endDate, DAYS)}.
* <p>
* There are two equivalent ways of using this method.
* The first is to invoke this method.
* The second is to use {@link TemporalUnit#between(Temporal, Temporal)}:
* <pre>
* // these two lines are equivalent
! * amount = start.periodUntil(end, MONTHS);
* amount = MONTHS.between(start, end);
* </pre>
* The choice should be made based on which makes the code more readable.
* <p>
* The calculation is implemented in this method for {@link ChronoUnit}.
--- 564,581 ----
* The {@code Temporal} passed to this method must be a
* {@code ChronoLocalDate} in the same chronology.
* The calculation returns a whole number, representing the number of
* complete units between the two dates.
* For example, the amount in days between two dates can be calculated
! * using {@code startDate.until(endDate, DAYS)}.
* <p>
* There are two equivalent ways of using this method.
* The first is to invoke this method.
* The second is to use {@link TemporalUnit#between(Temporal, Temporal)}:
* <pre>
* // these two lines are equivalent
! * amount = start.until(end, MONTHS);
* amount = MONTHS.between(start, end);
* </pre>
* The choice should be made based on which makes the code more readable.
* <p>
* The calculation is implemented in this method for {@link ChronoUnit}.
*** 553,563 ****
* @return the amount of time between this date and the end date
* @throws DateTimeException if the amount cannot be calculated
* @throws ArithmeticException if numeric overflow occurs
*/
@Override // override for Javadoc
! long periodUntil(Temporal endDate, TemporalUnit unit);
/**
* Calculates the period between this date and another date as a {@code Period}.
* <p>
* This calculates the period between two dates in terms of years, months and days.
--- 597,607 ----
* @return the amount of time between this date and the end date
* @throws DateTimeException if the amount cannot be calculated
* @throws ArithmeticException if numeric overflow occurs
*/
@Override // override for Javadoc
! long until(Temporal endDate, TemporalUnit unit);
/**
* Calculates the period between this date and another date as a {@code Period}.
* <p>
* This calculates the period between two dates in terms of years, months and days.
*** 573,583 ****
* @param endDate the end date, exclusive, which may be in any chronology, not null
* @return the period between this date and the end date, not null
* @throws DateTimeException if the period cannot be calculated
* @throws ArithmeticException if numeric overflow occurs
*/
! Period periodUntil(ChronoLocalDate<?> endDate);
/**
* Formats this date using the specified formatter.
* <p>
* This date will be passed to the formatter to produce a string.
--- 617,627 ----
* @param endDate the end date, exclusive, which may be in any chronology, not null
* @return the period between this date and the end date, not null
* @throws DateTimeException if the period cannot be calculated
* @throws ArithmeticException if numeric overflow occurs
*/
! Period until(ChronoLocalDate endDate);
/**
* Formats this date using the specified formatter.
* <p>
* This date will be passed to the formatter to produce a string.
*** 604,615 ****
* All possible combinations of date and time are valid.
*
* @param localTime the local time to use, not null
* @return the local date-time formed from this date and the specified time, not null
*/
! default ChronoLocalDateTime<D> atTime(LocalTime localTime) {
! return (ChronoLocalDateTime<D>)ChronoLocalDateTimeImpl.of(this, localTime);
}
//-----------------------------------------------------------------------
/**
* Converts this date to the Epoch Day.
--- 648,660 ----
* All possible combinations of date and time are valid.
*
* @param localTime the local time to use, not null
* @return the local date-time formed from this date and the specified time, not null
*/
! @SuppressWarnings("unchecked")
! default ChronoLocalDateTime<?> atTime(LocalTime localTime) {
! return ChronoLocalDateTimeImpl.of(this, localTime);
}
//-----------------------------------------------------------------------
/**
* Converts this date to the Epoch Day.
*** 654,664 ****
*
* @param other the other date to compare to, not null
* @return the comparator value, negative if less, positive if greater
*/
@Override
! default int compareTo(ChronoLocalDate<?> other) {
int cmp = Long.compare(toEpochDay(), other.toEpochDay());
if (cmp == 0) {
cmp = getChronology().compareTo(other.getChronology());
}
return cmp;
--- 699,709 ----
*
* @param other the other date to compare to, not null
* @return the comparator value, negative if less, positive if greater
*/
@Override
! default int compareTo(ChronoLocalDate other) {
int cmp = Long.compare(toEpochDay(), other.toEpochDay());
if (cmp == 0) {
cmp = getChronology().compareTo(other.getChronology());
}
return cmp;
*** 676,686 ****
* This default implementation performs the comparison based on the epoch-day.
*
* @param other the other date to compare to, not null
* @return true if this is after the specified date
*/
! default boolean isAfter(ChronoLocalDate<?> other) {
return this.toEpochDay() > other.toEpochDay();
}
/**
* Checks if this date is before the specified date ignoring the chronology.
--- 721,731 ----
* This default implementation performs the comparison based on the epoch-day.
*
* @param other the other date to compare to, not null
* @return true if this is after the specified date
*/
! default boolean isAfter(ChronoLocalDate other) {
return this.toEpochDay() > other.toEpochDay();
}
/**
* Checks if this date is before the specified date ignoring the chronology.
*** 694,704 ****
* This default implementation performs the comparison based on the epoch-day.
*
* @param other the other date to compare to, not null
* @return true if this is before the specified date
*/
! default boolean isBefore(ChronoLocalDate<?> other) {
return this.toEpochDay() < other.toEpochDay();
}
/**
* Checks if this date is equal to the specified date ignoring the chronology.
--- 739,749 ----
* This default implementation performs the comparison based on the epoch-day.
*
* @param other the other date to compare to, not null
* @return true if this is before the specified date
*/
! default boolean isBefore(ChronoLocalDate other) {
return this.toEpochDay() < other.toEpochDay();
}
/**
* Checks if this date is equal to the specified date ignoring the chronology.
*** 712,722 ****
* This default implementation performs the comparison based on the epoch-day.
*
* @param other the other date to compare to, not null
* @return true if the underlying date is equal to the specified date
*/
! default boolean isEqual(ChronoLocalDate<?> other) {
return this.toEpochDay() == other.toEpochDay();
}
//-----------------------------------------------------------------------
/**
--- 757,767 ----
* This default implementation performs the comparison based on the epoch-day.
*
* @param other the other date to compare to, not null
* @return true if the underlying date is equal to the specified date
*/
! default boolean isEqual(ChronoLocalDate other) {
return this.toEpochDay() == other.toEpochDay();
}
//-----------------------------------------------------------------------
/**