src/share/classes/java/time/chrono/ChronoLocalDate.java

Print this page

        

*** 57,77 **** * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ ! package java.time.temporal; import static java.time.temporal.ChronoField.EPOCH_DAY; import static java.time.temporal.ChronoField.ERA; import static java.time.temporal.ChronoField.YEAR; import static java.time.temporal.ChronoUnit.DAYS; import java.time.DateTimeException; import java.time.LocalDate; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.util.Comparator; import java.util.Objects; /** * A date without time-of-day or time-zone in an arbitrary chronology, intended --- 57,88 ---- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ ! package java.time.chrono; import static java.time.temporal.ChronoField.EPOCH_DAY; import static java.time.temporal.ChronoField.ERA; import static java.time.temporal.ChronoField.YEAR; import static java.time.temporal.ChronoUnit.DAYS; import java.time.DateTimeException; import java.time.LocalDate; import java.time.LocalTime; + import java.time.Period; import java.time.format.DateTimeFormatter; + import java.time.temporal.ChronoField; + import java.time.temporal.ChronoUnit; + import java.time.temporal.Queries; + import java.time.temporal.Temporal; + import java.time.temporal.TemporalAccessor; + import java.time.temporal.TemporalAdjuster; + import java.time.temporal.TemporalAmount; + import java.time.temporal.TemporalField; + import java.time.temporal.TemporalQuery; + import java.time.temporal.TemporalUnit; import java.util.Comparator; import java.util.Objects; /** * A date without time-of-day or time-zone in an arbitrary chronology, intended
*** 79,89 **** * <p> * <b>Most applications should declare method signatures, fields and variables * as {@link LocalDate}, not this interface.</b> * <p> * A {@code ChronoLocalDate} is the abstract representation of a date where the ! * {@code Chrono chronology}, or calendar system, is pluggable. * The date is defined in terms of fields expressed by {@link TemporalField}, * where most common implementations are defined in {@link ChronoField}. * The chronology defines how the calendar system operates and the meaning of * the standard fields. * --- 90,100 ---- * <p> * <b>Most applications should declare method signatures, fields and variables * as {@link LocalDate}, not this interface.</b> * <p> * A {@code ChronoLocalDate} is the abstract representation of a date where the ! * {@code Chronology chronology}, or calendar system, is pluggable. * The date is defined in terms of fields expressed by {@link TemporalField}, * where most common implementations are defined in {@link ChronoField}. * The chronology defines how the calendar system operates and the meaning of * the standard fields. *
*** 91,101 **** * The design of the API encourages the use of {@code LocalDate} rather than this * interface, even in the case where the application needs to deal with multiple * calendar systems. The rationale for this is explored in the following documentation. * <p> * The primary use case where this interface should be used is where the generic ! * type parameter {@code <C>} is fully defined as a specific chronology. * In that case, the assumptions of that chronology are known at development * time and specified in the code. * <p> * When the chronology is defined in the generic type parameter as ? or otherwise * unknown at development time, the rest of the discussion below applies. --- 102,112 ---- * The design of the API encourages the use of {@code LocalDate} rather than this * interface, even in the case where the application needs to deal with multiple * calendar systems. The rationale for this is explored in the following documentation. * <p> * The primary use case where this interface should be used is where the generic ! * type parameter {@code <D>} is fully defined as a specific chronology. * In that case, the assumptions of that chronology are known at development * time and specified in the code. * <p> * When the chronology is defined in the generic type parameter as ? or otherwise * unknown at development time, the rest of the discussion below applies.
*** 227,242 **** * This interface must be implemented with care to ensure other classes operate correctly. * All implementations that can be instantiated must be final, immutable and thread-safe. * Subclasses should be Serializable wherever possible. * <p> * Additional calendar systems may be added to the system. ! * See {@link Chrono} for more details. * ! * @param <C> the chronology of this date * @since 1.8 */ ! public interface ChronoLocalDate<C extends Chrono<C>> extends Temporal, TemporalAdjuster, Comparable<ChronoLocalDate<?>> { /** * Comparator for two {@code ChronoLocalDate}s ignoring the chronology. * <p> --- 238,253 ---- * This interface must be implemented with care to ensure other classes operate correctly. * All implementations that can be instantiated must be final, immutable and thread-safe. * 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<?>> { /** * Comparator for two {@code ChronoLocalDate}s ignoring the chronology. * <p>
*** 260,308 **** //----------------------------------------------------------------------- /** * Gets the chronology of this date. * <p> ! * The {@code Chrono} represents the calendar system in use. * The era and other fields in {@link ChronoField} are defined by the chronology. * * @return the chronology, not null */ ! C getChrono(); /** * Gets the era, as defined by the chronology. * <p> * The era is, conceptually, the largest division of the time-line. * Most calendar systems have a single epoch dividing the time-line into two eras. * However, some have multiple eras, such as one for the reign of each leader. ! * The exact meaning is determined by the {@code Chrono}. * <p> * All correctly implemented {@code Era} classes are singletons, thus it * is valid code to write {@code date.getEra() == SomeChrono.ERA_NAME)}. * <p> ! * This default implementation uses {@link Chrono#eraOf(int)}. * * @return the chronology specific era constant applicable at this date, not null */ ! public default Era<C> getEra() { ! return getChrono().eraOf(get(ERA)); } /** * Checks if the year is a leap year, as defined by the calendar system. * <p> * A leap-year is a year of a longer length than normal. * The exact meaning is determined by the chronology with the constraint that * a leap-year must imply a year-length longer than a non leap-year. * <p> ! * This default implementation uses {@link Chrono#isLeapYear(long)}. * * @return true if this date is in a leap year, false otherwise */ public default boolean isLeapYear() { ! return getChrono().isLeapYear(getLong(YEAR)); } /** * Returns the length of the month represented by this date, as defined by the calendar system. * <p> --- 271,319 ---- //----------------------------------------------------------------------- /** * Gets the chronology of this date. * <p> ! * The {@code Chronology} represents the calendar system in use. * The era and other fields in {@link ChronoField} are defined by the chronology. * * @return the chronology, not null */ ! Chronology getChronology(); /** * Gets the era, as defined by the chronology. * <p> * The era is, conceptually, the largest division of the time-line. * Most calendar systems have a single epoch dividing the time-line into two eras. * However, some have multiple eras, such as one for the reign of each leader. ! * The exact meaning is determined by the {@code Chronology}. * <p> * All correctly implemented {@code Era} classes are singletons, thus it * is valid code to write {@code date.getEra() == SomeChrono.ERA_NAME)}. * <p> ! * This default implementation uses {@link Chronology#eraOf(int)}. * * @return the chronology specific era constant applicable at this date, not null */ ! public default Era getEra() { ! return getChronology().eraOf(get(ERA)); } /** * Checks if the year is a leap year, as defined by the calendar system. * <p> * A leap-year is a year of a longer length than normal. * The exact meaning is determined by the chronology with the constraint that * a leap-year must imply a year-length longer than a non leap-year. * <p> ! * This default implementation uses {@link Chronology#isLeapYear(long)}. * * @return true if this date is in a leap year, false otherwise */ public default boolean isLeapYear() { ! return getChronology().isLeapYear(getLong(YEAR)); } /** * Returns the length of the month represented by this date, as defined by the calendar system. * <p>
*** 328,406 **** @Override public default boolean isSupported(TemporalField field) { if (field instanceof ChronoField) { return ((ChronoField) field).isDateField(); } ! return field != null && field.doIsSupported(this); } //----------------------------------------------------------------------- // override for covariant return type /** * {@inheritDoc} * @throws DateTimeException {@inheritDoc} * @throws ArithmeticException {@inheritDoc} */ @Override ! public default ChronoLocalDate<C> with(TemporalAdjuster adjuster) { ! return getChrono().ensureChronoLocalDate(Temporal.super.with(adjuster)); } /** * {@inheritDoc} * @throws DateTimeException {@inheritDoc} * @throws ArithmeticException {@inheritDoc} */ @Override ! public default ChronoLocalDate<C> with(TemporalField field, long newValue) { if (field instanceof ChronoField) { throw new DateTimeException("Unsupported field: " + field.getName()); } ! return getChrono().ensureChronoLocalDate(field.doWith(this, newValue)); } /** * {@inheritDoc} * @throws DateTimeException {@inheritDoc} * @throws ArithmeticException {@inheritDoc} */ @Override ! public default ChronoLocalDate<C> plus(TemporalAdder adder) { ! return getChrono().ensureChronoLocalDate(Temporal.super.plus(adder)); } /** * {@inheritDoc} * @throws DateTimeException {@inheritDoc} * @throws ArithmeticException {@inheritDoc} */ @Override ! public default ChronoLocalDate<C> plus(long amountToAdd, TemporalUnit unit) { if (unit instanceof ChronoUnit) { throw new DateTimeException("Unsupported unit: " + unit.getName()); } ! return getChrono().ensureChronoLocalDate(unit.doPlus(this, amountToAdd)); } /** * {@inheritDoc} * @throws DateTimeException {@inheritDoc} * @throws ArithmeticException {@inheritDoc} */ @Override ! public default ChronoLocalDate<C> minus(TemporalSubtractor subtractor) { ! return getChrono().ensureChronoLocalDate(Temporal.super.minus(subtractor)); } /** * {@inheritDoc} * @throws DateTimeException {@inheritDoc} * @throws ArithmeticException {@inheritDoc} */ @Override ! public default ChronoLocalDate<C> minus(long amountToSubtract, TemporalUnit unit) { ! return getChrono().ensureChronoLocalDate(Temporal.super.minus(amountToSubtract, unit)); } //----------------------------------------------------------------------- /** * Queries this date using the specified query. --- 339,417 ---- @Override public default boolean isSupported(TemporalField field) { if (field instanceof ChronoField) { return ((ChronoField) field).isDateField(); } ! return field != null && field.isSupportedBy(this); } //----------------------------------------------------------------------- // override for covariant return type /** * {@inheritDoc} * @throws DateTimeException {@inheritDoc} * @throws ArithmeticException {@inheritDoc} */ @Override ! public default D with(TemporalAdjuster adjuster) { ! return (D) getChronology().ensureChronoLocalDate(Temporal.super.with(adjuster)); } /** * {@inheritDoc} * @throws DateTimeException {@inheritDoc} * @throws ArithmeticException {@inheritDoc} */ @Override ! public default D with(TemporalField field, long newValue) { if (field instanceof ChronoField) { throw new DateTimeException("Unsupported field: " + field.getName()); } ! return (D) getChronology().ensureChronoLocalDate(field.adjustInto(this, newValue)); } /** * {@inheritDoc} * @throws DateTimeException {@inheritDoc} * @throws ArithmeticException {@inheritDoc} */ @Override ! public default D plus(TemporalAmount amount) { ! return (D) getChronology().ensureChronoLocalDate(Temporal.super.plus(amount)); } /** * {@inheritDoc} * @throws DateTimeException {@inheritDoc} * @throws ArithmeticException {@inheritDoc} */ @Override ! public default D plus(long amountToAdd, TemporalUnit unit) { if (unit instanceof ChronoUnit) { throw new DateTimeException("Unsupported unit: " + unit.getName()); } ! return (D) getChronology().ensureChronoLocalDate(unit.addTo(this, amountToAdd)); } /** * {@inheritDoc} * @throws DateTimeException {@inheritDoc} * @throws ArithmeticException {@inheritDoc} */ @Override ! public default D minus(TemporalAmount amount) { ! return (D) getChronology().ensureChronoLocalDate(Temporal.super.minus(amount)); } /** * {@inheritDoc} * @throws DateTimeException {@inheritDoc} * @throws ArithmeticException {@inheritDoc} */ @Override ! public default D minus(long amountToSubtract, TemporalUnit unit) { ! return (D) getChronology().ensureChronoLocalDate(Temporal.super.minus(amountToSubtract, unit)); } //----------------------------------------------------------------------- /** * Queries this date using the specified query.
*** 421,440 **** * @throws ArithmeticException if numeric overflow occurs (defined by the query) */ @SuppressWarnings("unchecked") @Override public default <R> R query(TemporalQuery<R> query) { - if (query == Queries.chrono()) { - return (R) getChrono(); - } - if (query == Queries.precision()) { - return (R) DAYS; - } - // inline TemporalAccessor.super.query(query) as an optimization if (query == Queries.zoneId() || query == Queries.zone() || query == Queries.offset()) { return null; } return query.queryFrom(this); } /** * Adjusts the specified temporal object to have the same date as this object. --- 432,452 ---- * @throws ArithmeticException if numeric overflow occurs (defined by the query) */ @SuppressWarnings("unchecked") @Override public default <R> R query(TemporalQuery<R> query) { if (query == Queries.zoneId() || query == Queries.zone() || query == Queries.offset()) { return null; + } else if (query == Queries.localTime()) { + return null; + } else if (query == Queries.chronology()) { + return (R) getChronology(); + } else if (query == Queries.precision()) { + return (R) DAYS; } + // inline TemporalAccessor.super.query(query) as an optimization + // non-JDK classes are not permitted to make this optimization return query.queryFrom(this); } /** * Adjusts the specified temporal object to have the same date as this object.
*** 477,494 **** * The calculation returns a whole number, representing the number of * complete units between the two dates. * For example, the period in days between two dates can be calculated * using {@code startDate.periodUntil(endDate, DAYS)}. * <p> ! * This method operates in association with {@link TemporalUnit#between}. ! * The result of this method is a {@code long} representing the amount of ! * the specified unit. By contrast, the result of {@code between} is an ! * object that can be used directly in addition/subtraction: * <pre> ! * long period = start.periodUntil(end, MONTHS); // this method ! * dateTime.plus(MONTHS.between(start, end)); // use in plus/minus * </pre> * <p> * The calculation is implemented in this method for {@link ChronoUnit}. * The units {@code DAYS}, {@code WEEKS}, {@code MONTHS}, {@code YEARS}, * {@code DECADES}, {@code CENTURIES}, {@code MILLENNIA} and {@code ERAS} * should be supported by all implementations. --- 489,507 ---- * The calculation returns a whole number, representing the number of * complete units between the two dates. * For example, the period 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}. * The units {@code DAYS}, {@code WEEKS}, {@code MONTHS}, {@code YEARS}, * {@code DECADES}, {@code CENTURIES}, {@code MILLENNIA} and {@code ERAS} * should be supported by all implementations.
*** 509,534 **** * @throws ArithmeticException if numeric overflow occurs */ @Override // override for Javadoc public abstract long periodUntil(Temporal endDate, TemporalUnit unit); - //----------------------------------------------------------------------- /** ! * Returns a date-time formed from this date at the specified time. * <p> ! * This merges the two objects - {@code this} and the specified time - ! * to form an instance of {@code ChronoLocalDateTime}. * <p> * This instance is immutable and unaffected by this method call. * <p> ! * This default implementation creates the date-time. * * @param localTime the local time to use, not null * @return the local date-time formed from this date and the specified time, not null */ ! public default ChronoLocalDateTime<C> atTime(LocalTime localTime) { ! return Chrono.dateTime(this, localTime); } //----------------------------------------------------------------------- /** * Converts this date to the Epoch Day. --- 522,565 ---- * @throws ArithmeticException if numeric overflow occurs */ @Override // override for Javadoc public abstract 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. ! * The start and end points are {@code this} and the specified date. ! * The result will be negative if the end is before the start. ! * <p> ! * The calculation is performed using the the chronology of this date. ! * If necessary, the input date will be converted to match. ! * <p> ! * The result of this method can be a negative period if the end is before the start. ! * The negative sign will be the same in each of year, month and day. * <p> * This instance is immutable and unaffected by this method call. + * + * @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 + */ + public abstract Period periodUntil(ChronoLocalDate<?> endDate); + + //----------------------------------------------------------------------- + /** + * Combines this date with a time to create a {@code ChronoLocalDateTime}. * <p> ! * This returns a {@code ChronoLocalDateTime} formed from this date at the specified time. ! * 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 */ ! public default ChronoLocalDateTime<D> atTime(LocalTime localTime) { ! return (ChronoLocalDateTime<D>)ChronoLocalDateTimeImpl.of(this, localTime); } //----------------------------------------------------------------------- /** * Converts this date to the Epoch Day.
*** 576,586 **** */ @Override public default int compareTo(ChronoLocalDate<?> other) { int cmp = Long.compare(toEpochDay(), other.toEpochDay()); if (cmp == 0) { ! cmp = getChrono().compareTo(other.getChrono()); } return cmp; } /** --- 607,617 ---- */ @Override public default int compareTo(ChronoLocalDate<?> other) { int cmp = Long.compare(toEpochDay(), other.toEpochDay()); if (cmp == 0) { ! cmp = getChronology().compareTo(other.getChronology()); } return cmp; } /**
*** 674,691 **** /** * Outputs this date as a {@code String} using the formatter. * <p> * The default implementation must behave as follows: * <pre> ! * return formatter.print(this); * </pre> * * @param formatter the formatter to use, not null * @return the formatted date string, not null * @throws DateTimeException if an error occurs during printing */ public default String toString(DateTimeFormatter formatter) { Objects.requireNonNull(formatter, "formatter"); ! return formatter.print(this); } } --- 705,722 ---- /** * Outputs this date as a {@code String} using the formatter. * <p> * The default implementation must behave as follows: * <pre> ! * return formatter.format(this); * </pre> * * @param formatter the formatter to use, not null * @return the formatted date string, not null * @throws DateTimeException if an error occurs during printing */ public default String toString(DateTimeFormatter formatter) { Objects.requireNonNull(formatter, "formatter"); ! return formatter.format(this); } }