jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java
changeset 19030 32f129cb6351
parent 17474 8c100beabcc0
child 20518 dde564773845
equal deleted inserted replaced
19029:30c64a024c86 19030:32f129cb6351
   240  * Subclasses should be Serializable wherever possible.
   240  * Subclasses should be Serializable wherever possible.
   241  * <p>
   241  * <p>
   242  * Additional calendar systems may be added to the system.
   242  * Additional calendar systems may be added to the system.
   243  * See {@link Chronology} for more details.
   243  * See {@link Chronology} for more details.
   244  *
   244  *
   245  * @param <D> the concrete type for the date
       
   246  * @since 1.8
   245  * @since 1.8
   247  */
   246  */
   248 public interface ChronoLocalDate<D extends ChronoLocalDate<D>>
   247 public interface ChronoLocalDate
   249         extends Temporal, TemporalAdjuster, Comparable<ChronoLocalDate<?>> {
   248         extends Temporal, TemporalAdjuster, Comparable<ChronoLocalDate> {
   250 
   249 
   251     /**
   250     /**
   252      * Gets a comparator that compares {@code ChronoLocalDate} in
   251      * Gets a comparator that compares {@code ChronoLocalDate} in
   253      * time-line order ignoring the chronology.
   252      * time-line order ignoring the chronology.
   254      * <p>
   253      * <p>
   261      *
   260      *
   262      * @see #isAfter
   261      * @see #isAfter
   263      * @see #isBefore
   262      * @see #isBefore
   264      * @see #isEqual
   263      * @see #isEqual
   265      */
   264      */
   266     static Comparator<ChronoLocalDate<?>> timeLineOrder() {
   265     static Comparator<ChronoLocalDate> timeLineOrder() {
   267         return Chronology.DATE_ORDER;
   266         return Chronology.DATE_ORDER;
   268     }
   267     }
   269 
   268 
   270     //-----------------------------------------------------------------------
   269     //-----------------------------------------------------------------------
   271     /**
   270     /**
   287      * @param temporal  the temporal object to convert, not null
   286      * @param temporal  the temporal object to convert, not null
   288      * @return the date, not null
   287      * @return the date, not null
   289      * @throws DateTimeException if unable to convert to a {@code ChronoLocalDate}
   288      * @throws DateTimeException if unable to convert to a {@code ChronoLocalDate}
   290      * @see Chronology#date(TemporalAccessor)
   289      * @see Chronology#date(TemporalAccessor)
   291      */
   290      */
   292     static ChronoLocalDate<?> from(TemporalAccessor temporal) {
   291     static ChronoLocalDate from(TemporalAccessor temporal) {
   293         if (temporal instanceof ChronoLocalDate) {
   292         if (temporal instanceof ChronoLocalDate) {
   294             return (ChronoLocalDate<?>) temporal;
   293             return (ChronoLocalDate) temporal;
   295         }
   294         }
   296         Chronology chrono = temporal.query(TemporalQuery.chronology());
   295         Chronology chrono = temporal.query(TemporalQuery.chronology());
   297         if (chrono == null) {
   296         if (chrono == null) {
   298             throw new DateTimeException("Unable to obtain ChronoLocalDate from TemporalAccessor: " + temporal.getClass());
   297             throw new DateTimeException("Unable to obtain ChronoLocalDate from TemporalAccessor: " + temporal.getClass());
   299         }
   298         }
   365      */
   364      */
   366     default int lengthOfYear() {
   365     default int lengthOfYear() {
   367         return (isLeapYear() ? 366 : 365);
   366         return (isLeapYear() ? 366 : 365);
   368     }
   367     }
   369 
   368 
       
   369     /**
       
   370      * Checks if the specified field is supported.
       
   371      * <p>
       
   372      * This checks if the specified field can be queried on this date.
       
   373      * If false, then calling the {@link #range(TemporalField) range},
       
   374      * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)}
       
   375      * methods will throw an exception.
       
   376      * <p>
       
   377      * The set of supported fields is defined by the chronology and normally includes
       
   378      * all {@code ChronoField} date fields.
       
   379      * <p>
       
   380      * If the field is not a {@code ChronoField}, then the result of this method
       
   381      * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
       
   382      * passing {@code this} as the argument.
       
   383      * Whether the field is supported is determined by the field.
       
   384      *
       
   385      * @param field  the field to check, null returns false
       
   386      * @return true if the field can be queried, false if not
       
   387      */
   370     @Override
   388     @Override
   371     default boolean isSupported(TemporalField field) {
   389     default boolean isSupported(TemporalField field) {
   372         if (field instanceof ChronoField) {
   390         if (field instanceof ChronoField) {
   373             return field.isDateBased();
   391             return field.isDateBased();
   374         }
   392         }
   375         return field != null && field.isSupportedBy(this);
   393         return field != null && field.isSupportedBy(this);
   376     }
   394     }
   377 
   395 
       
   396     /**
       
   397      * Checks if the specified unit is supported.
       
   398      * <p>
       
   399      * This checks if the specified unit can be added to or subtracted from this date.
       
   400      * If false, then calling the {@link #plus(long, TemporalUnit)} and
       
   401      * {@link #minus(long, TemporalUnit) minus} methods will throw an exception.
       
   402      * <p>
       
   403      * The set of supported units is defined by the chronology and normally includes
       
   404      * all {@code ChronoUnit} date units except {@code FOREVER}.
       
   405      * <p>
       
   406      * If the unit is not a {@code ChronoUnit}, then the result of this method
       
   407      * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)}
       
   408      * passing {@code this} as the argument.
       
   409      * Whether the unit is supported is determined by the unit.
       
   410      *
       
   411      * @param unit  the unit to check, null returns false
       
   412      * @return true if the unit can be added/subtracted, false if not
       
   413      */
       
   414     @Override
       
   415     default boolean isSupported(TemporalUnit unit) {
       
   416         if (unit instanceof ChronoUnit) {
       
   417             return unit.isDateBased();
       
   418         }
       
   419         return unit != null && unit.isSupportedBy(this);
       
   420     }
       
   421 
   378     //-----------------------------------------------------------------------
   422     //-----------------------------------------------------------------------
   379     // override for covariant return type
   423     // override for covariant return type
   380     /**
   424     /**
   381      * {@inheritDoc}
   425      * {@inheritDoc}
   382      * @throws DateTimeException {@inheritDoc}
   426      * @throws DateTimeException {@inheritDoc}
   383      * @throws ArithmeticException {@inheritDoc}
   427      * @throws ArithmeticException {@inheritDoc}
   384      */
   428      */
   385     @Override
   429     @Override
   386     default D with(TemporalAdjuster adjuster) {
   430     default ChronoLocalDate with(TemporalAdjuster adjuster) {
   387         return (D) getChronology().ensureChronoLocalDate(Temporal.super.with(adjuster));
   431         return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.with(adjuster));
   388     }
   432     }
   389 
   433 
   390     /**
   434     /**
   391      * {@inheritDoc}
   435      * {@inheritDoc}
   392      * @throws DateTimeException {@inheritDoc}
   436      * @throws DateTimeException {@inheritDoc}
   393      * @throws UnsupportedTemporalTypeException {@inheritDoc}
   437      * @throws UnsupportedTemporalTypeException {@inheritDoc}
   394      * @throws ArithmeticException {@inheritDoc}
   438      * @throws ArithmeticException {@inheritDoc}
   395      */
   439      */
   396     @Override
   440     @Override
   397     default D with(TemporalField field, long newValue) {
   441     default ChronoLocalDate with(TemporalField field, long newValue) {
   398         if (field instanceof ChronoField) {
   442         if (field instanceof ChronoField) {
   399             throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName());
   443             throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
   400         }
   444         }
   401         return (D) getChronology().ensureChronoLocalDate(field.adjustInto(this, newValue));
   445         return ChronoDateImpl.ensureValid(getChronology(), field.adjustInto(this, newValue));
   402     }
   446     }
   403 
   447 
   404     /**
   448     /**
   405      * {@inheritDoc}
   449      * {@inheritDoc}
   406      * @throws DateTimeException {@inheritDoc}
   450      * @throws DateTimeException {@inheritDoc}
   407      * @throws ArithmeticException {@inheritDoc}
   451      * @throws ArithmeticException {@inheritDoc}
   408      */
   452      */
   409     @Override
   453     @Override
   410     default D plus(TemporalAmount amount) {
   454     default ChronoLocalDate plus(TemporalAmount amount) {
   411         return (D) getChronology().ensureChronoLocalDate(Temporal.super.plus(amount));
   455         return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.plus(amount));
   412     }
   456     }
   413 
   457 
   414     /**
   458     /**
   415      * {@inheritDoc}
   459      * {@inheritDoc}
   416      * @throws DateTimeException {@inheritDoc}
   460      * @throws DateTimeException {@inheritDoc}
   417      * @throws ArithmeticException {@inheritDoc}
   461      * @throws ArithmeticException {@inheritDoc}
   418      */
   462      */
   419     @Override
   463     @Override
   420     default D plus(long amountToAdd, TemporalUnit unit) {
   464     default ChronoLocalDate plus(long amountToAdd, TemporalUnit unit) {
   421         if (unit instanceof ChronoUnit) {
   465         if (unit instanceof ChronoUnit) {
   422             throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName());
   466             throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
   423         }
   467         }
   424         return (D) getChronology().ensureChronoLocalDate(unit.addTo(this, amountToAdd));
   468         return ChronoDateImpl.ensureValid(getChronology(), unit.addTo(this, amountToAdd));
   425     }
   469     }
   426 
   470 
   427     /**
   471     /**
   428      * {@inheritDoc}
   472      * {@inheritDoc}
   429      * @throws DateTimeException {@inheritDoc}
   473      * @throws DateTimeException {@inheritDoc}
   430      * @throws ArithmeticException {@inheritDoc}
   474      * @throws ArithmeticException {@inheritDoc}
   431      */
   475      */
   432     @Override
   476     @Override
   433     default D minus(TemporalAmount amount) {
   477     default ChronoLocalDate minus(TemporalAmount amount) {
   434         return (D) getChronology().ensureChronoLocalDate(Temporal.super.minus(amount));
   478         return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.minus(amount));
   435     }
   479     }
   436 
   480 
   437     /**
   481     /**
   438      * {@inheritDoc}
   482      * {@inheritDoc}
   439      * @throws DateTimeException {@inheritDoc}
   483      * @throws DateTimeException {@inheritDoc}
   440      * @throws UnsupportedTemporalTypeException {@inheritDoc}
   484      * @throws UnsupportedTemporalTypeException {@inheritDoc}
   441      * @throws ArithmeticException {@inheritDoc}
   485      * @throws ArithmeticException {@inheritDoc}
   442      */
   486      */
   443     @Override
   487     @Override
   444     default D minus(long amountToSubtract, TemporalUnit unit) {
   488     default ChronoLocalDate minus(long amountToSubtract, TemporalUnit unit) {
   445         return (D) getChronology().ensureChronoLocalDate(Temporal.super.minus(amountToSubtract, unit));
   489         return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.minus(amountToSubtract, unit));
   446     }
   490     }
   447 
   491 
   448     //-----------------------------------------------------------------------
   492     //-----------------------------------------------------------------------
   449     /**
   493     /**
   450      * Queries this date using the specified query.
   494      * Queries this date using the specified query.
   520      * The {@code Temporal} passed to this method must be a
   564      * The {@code Temporal} passed to this method must be a
   521      * {@code ChronoLocalDate} in the same chronology.
   565      * {@code ChronoLocalDate} in the same chronology.
   522      * The calculation returns a whole number, representing the number of
   566      * The calculation returns a whole number, representing the number of
   523      * complete units between the two dates.
   567      * complete units between the two dates.
   524      * For example, the amount in days between two dates can be calculated
   568      * For example, the amount in days between two dates can be calculated
   525      * using {@code startDate.periodUntil(endDate, DAYS)}.
   569      * using {@code startDate.until(endDate, DAYS)}.
   526      * <p>
   570      * <p>
   527      * There are two equivalent ways of using this method.
   571      * There are two equivalent ways of using this method.
   528      * The first is to invoke this method.
   572      * The first is to invoke this method.
   529      * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}:
   573      * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}:
   530      * <pre>
   574      * <pre>
   531      *   // these two lines are equivalent
   575      *   // these two lines are equivalent
   532      *   amount = start.periodUntil(end, MONTHS);
   576      *   amount = start.until(end, MONTHS);
   533      *   amount = MONTHS.between(start, end);
   577      *   amount = MONTHS.between(start, end);
   534      * </pre>
   578      * </pre>
   535      * The choice should be made based on which makes the code more readable.
   579      * The choice should be made based on which makes the code more readable.
   536      * <p>
   580      * <p>
   537      * The calculation is implemented in this method for {@link ChronoUnit}.
   581      * The calculation is implemented in this method for {@link ChronoUnit}.
   553      * @return the amount of time between this date and the end date
   597      * @return the amount of time between this date and the end date
   554      * @throws DateTimeException if the amount cannot be calculated
   598      * @throws DateTimeException if the amount cannot be calculated
   555      * @throws ArithmeticException if numeric overflow occurs
   599      * @throws ArithmeticException if numeric overflow occurs
   556      */
   600      */
   557     @Override  // override for Javadoc
   601     @Override  // override for Javadoc
   558     long periodUntil(Temporal endDate, TemporalUnit unit);
   602     long until(Temporal endDate, TemporalUnit unit);
   559 
   603 
   560     /**
   604     /**
   561      * Calculates the period between this date and another date as a {@code Period}.
   605      * Calculates the period between this date and another date as a {@code Period}.
   562      * <p>
   606      * <p>
   563      * This calculates the period between two dates in terms of years, months and days.
   607      * This calculates the period between two dates in terms of years, months and days.
   573      * @param endDate  the end date, exclusive, which may be in any chronology, not null
   617      * @param endDate  the end date, exclusive, which may be in any chronology, not null
   574      * @return the period between this date and the end date, not null
   618      * @return the period between this date and the end date, not null
   575      * @throws DateTimeException if the period cannot be calculated
   619      * @throws DateTimeException if the period cannot be calculated
   576      * @throws ArithmeticException if numeric overflow occurs
   620      * @throws ArithmeticException if numeric overflow occurs
   577      */
   621      */
   578     Period periodUntil(ChronoLocalDate<?> endDate);
   622     Period until(ChronoLocalDate endDate);
   579 
   623 
   580     /**
   624     /**
   581      * Formats this date using the specified formatter.
   625      * Formats this date using the specified formatter.
   582      * <p>
   626      * <p>
   583      * This date will be passed to the formatter to produce a string.
   627      * This date will be passed to the formatter to produce a string.
   604      * All possible combinations of date and time are valid.
   648      * All possible combinations of date and time are valid.
   605      *
   649      *
   606      * @param localTime  the local time to use, not null
   650      * @param localTime  the local time to use, not null
   607      * @return the local date-time formed from this date and the specified time, not null
   651      * @return the local date-time formed from this date and the specified time, not null
   608      */
   652      */
   609     default ChronoLocalDateTime<D> atTime(LocalTime localTime) {
   653     @SuppressWarnings("unchecked")
   610         return (ChronoLocalDateTime<D>)ChronoLocalDateTimeImpl.of(this, localTime);
   654     default ChronoLocalDateTime<?> atTime(LocalTime localTime) {
       
   655         return ChronoLocalDateTimeImpl.of(this, localTime);
   611     }
   656     }
   612 
   657 
   613     //-----------------------------------------------------------------------
   658     //-----------------------------------------------------------------------
   614     /**
   659     /**
   615      * Converts this date to the Epoch Day.
   660      * Converts this date to the Epoch Day.
   654      *
   699      *
   655      * @param other  the other date to compare to, not null
   700      * @param other  the other date to compare to, not null
   656      * @return the comparator value, negative if less, positive if greater
   701      * @return the comparator value, negative if less, positive if greater
   657      */
   702      */
   658     @Override
   703     @Override
   659     default int compareTo(ChronoLocalDate<?> other) {
   704     default int compareTo(ChronoLocalDate other) {
   660         int cmp = Long.compare(toEpochDay(), other.toEpochDay());
   705         int cmp = Long.compare(toEpochDay(), other.toEpochDay());
   661         if (cmp == 0) {
   706         if (cmp == 0) {
   662             cmp = getChronology().compareTo(other.getChronology());
   707             cmp = getChronology().compareTo(other.getChronology());
   663         }
   708         }
   664         return cmp;
   709         return cmp;
   676      * This default implementation performs the comparison based on the epoch-day.
   721      * This default implementation performs the comparison based on the epoch-day.
   677      *
   722      *
   678      * @param other  the other date to compare to, not null
   723      * @param other  the other date to compare to, not null
   679      * @return true if this is after the specified date
   724      * @return true if this is after the specified date
   680      */
   725      */
   681     default boolean isAfter(ChronoLocalDate<?> other) {
   726     default boolean isAfter(ChronoLocalDate other) {
   682         return this.toEpochDay() > other.toEpochDay();
   727         return this.toEpochDay() > other.toEpochDay();
   683     }
   728     }
   684 
   729 
   685     /**
   730     /**
   686      * Checks if this date is before the specified date ignoring the chronology.
   731      * Checks if this date is before the specified date ignoring the chronology.
   694      * This default implementation performs the comparison based on the epoch-day.
   739      * This default implementation performs the comparison based on the epoch-day.
   695      *
   740      *
   696      * @param other  the other date to compare to, not null
   741      * @param other  the other date to compare to, not null
   697      * @return true if this is before the specified date
   742      * @return true if this is before the specified date
   698      */
   743      */
   699     default boolean isBefore(ChronoLocalDate<?> other) {
   744     default boolean isBefore(ChronoLocalDate other) {
   700         return this.toEpochDay() < other.toEpochDay();
   745         return this.toEpochDay() < other.toEpochDay();
   701     }
   746     }
   702 
   747 
   703     /**
   748     /**
   704      * Checks if this date is equal to the specified date ignoring the chronology.
   749      * Checks if this date is equal to the specified date ignoring the chronology.
   712      * This default implementation performs the comparison based on the epoch-day.
   757      * This default implementation performs the comparison based on the epoch-day.
   713      *
   758      *
   714      * @param other  the other date to compare to, not null
   759      * @param other  the other date to compare to, not null
   715      * @return true if the underlying date is equal to the specified date
   760      * @return true if the underlying date is equal to the specified date
   716      */
   761      */
   717     default boolean isEqual(ChronoLocalDate<?> other) {
   762     default boolean isEqual(ChronoLocalDate other) {
   718         return this.toEpochDay() == other.toEpochDay();
   763         return this.toEpochDay() == other.toEpochDay();
   719     }
   764     }
   720 
   765 
   721     //-----------------------------------------------------------------------
   766     //-----------------------------------------------------------------------
   722     /**
   767     /**