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

Print this page

        

@@ -57,21 +57,32 @@
  * 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;
+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,11 +90,11 @@
  * <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.
+ * {@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,11 +102,11 @@
  * 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.
+ * 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,16 +238,16 @@
  * 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.
+ * See {@link Chronology} for more details.
  *
- * @param <C> the chronology of this date
+ * @param <D> the concrete type for the date
  * @since 1.8
  */
-public interface ChronoLocalDate<C extends Chrono<C>>
+public interface ChronoLocalDate<D extends ChronoLocalDate<D>>
         extends Temporal, TemporalAdjuster, Comparable<ChronoLocalDate<?>> {
 
     /**
      * Comparator for two {@code ChronoLocalDate}s ignoring the chronology.
      * <p>

@@ -260,49 +271,49 @@
 
     //-----------------------------------------------------------------------
     /**
      * Gets the chronology of this date.
      * <p>
-     * The {@code Chrono} represents the calendar system in use.
+     * 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
      */
-    C getChrono();
+    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 Chrono}.
+     * 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 Chrono#eraOf(int)}.
+     * This default implementation uses {@link Chronology#eraOf(int)}.
      *
      * @return the chronology specific era constant applicable at this date, not null
      */
-    public default Era<C> getEra() {
-        return getChrono().eraOf(get(ERA));
+    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 Chrono#isLeapYear(long)}.
+     * 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 getChrono().isLeapYear(getLong(YEAR));
+        return getChronology().isLeapYear(getLong(YEAR));
     }
 
     /**
      * Returns the length of the month represented by this date, as defined by the calendar system.
      * <p>

@@ -328,79 +339,79 @@
     @Override
     public default boolean isSupported(TemporalField field) {
         if (field instanceof ChronoField) {
             return ((ChronoField) field).isDateField();
         }
-        return field != null && field.doIsSupported(this);
+        return field != null && field.isSupportedBy(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));
+    public default D with(TemporalAdjuster adjuster) {
+        return (D) getChronology().ensureChronoLocalDate(Temporal.super.with(adjuster));
     }
 
     /**
      * {@inheritDoc}
      * @throws DateTimeException {@inheritDoc}
      * @throws ArithmeticException {@inheritDoc}
      */
     @Override
-    public default ChronoLocalDate<C> with(TemporalField field, long newValue) {
+    public default D with(TemporalField field, long newValue) {
         if (field instanceof ChronoField) {
             throw new DateTimeException("Unsupported field: " + field.getName());
         }
-        return getChrono().ensureChronoLocalDate(field.doWith(this, newValue));
+        return (D) getChronology().ensureChronoLocalDate(field.adjustInto(this, newValue));
     }
 
     /**
      * {@inheritDoc}
      * @throws DateTimeException {@inheritDoc}
      * @throws ArithmeticException {@inheritDoc}
      */
     @Override
-    public default ChronoLocalDate<C> plus(TemporalAdder adder) {
-        return getChrono().ensureChronoLocalDate(Temporal.super.plus(adder));
+    public default D plus(TemporalAmount amount) {
+        return (D) getChronology().ensureChronoLocalDate(Temporal.super.plus(amount));
     }
 
     /**
      * {@inheritDoc}
      * @throws DateTimeException {@inheritDoc}
      * @throws ArithmeticException {@inheritDoc}
      */
     @Override
-    public default ChronoLocalDate<C> plus(long amountToAdd, TemporalUnit unit) {
+    public default D plus(long amountToAdd, TemporalUnit unit) {
         if (unit instanceof ChronoUnit) {
             throw new DateTimeException("Unsupported unit: " + unit.getName());
         }
-        return getChrono().ensureChronoLocalDate(unit.doPlus(this, amountToAdd));
+        return (D) getChronology().ensureChronoLocalDate(unit.addTo(this, amountToAdd));
     }
 
     /**
      * {@inheritDoc}
      * @throws DateTimeException {@inheritDoc}
      * @throws ArithmeticException {@inheritDoc}
      */
     @Override
-    public default ChronoLocalDate<C> minus(TemporalSubtractor subtractor) {
-        return getChrono().ensureChronoLocalDate(Temporal.super.minus(subtractor));
+    public default D minus(TemporalAmount amount) {
+        return (D) getChronology().ensureChronoLocalDate(Temporal.super.minus(amount));
     }
 
     /**
      * {@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));
+    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,20 +432,21 @@
      * @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;
+        } 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,18 +489,19 @@
      * 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:
+     * 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>
-     *   long period = start.periodUntil(end, MONTHS);   // this method
-     *   dateTime.plus(MONTHS.between(start, end));      // use in plus/minus
+     *   // 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,26 +522,44 @@
      * @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.
+     * Calculates the period between this date and another date as a {@code Period}.
      * <p>
-     * This merges the two objects - {@code this} and the specified time -
-     * to form an instance of {@code ChronoLocalDateTime}.
+     * 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 default implementation creates the date-time.
+     * 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<C> atTime(LocalTime localTime) {
-        return Chrono.dateTime(this, localTime);
+    public default ChronoLocalDateTime<D> atTime(LocalTime localTime) {
+        return (ChronoLocalDateTime<D>)ChronoLocalDateTimeImpl.of(this, localTime);
     }
 
     //-----------------------------------------------------------------------
     /**
      * Converts this date to the Epoch Day.

@@ -576,11 +607,11 @@
      */
     @Override
     public default int compareTo(ChronoLocalDate<?> other) {
         int cmp = Long.compare(toEpochDay(), other.toEpochDay());
         if (cmp == 0) {
-            cmp = getChrono().compareTo(other.getChrono());
+            cmp = getChronology().compareTo(other.getChronology());
         }
         return cmp;
     }
 
     /**

@@ -674,18 +705,18 @@
     /**
      * Outputs this date as a {@code String} using the formatter.
      * <p>
      * The default implementation must behave as follows:
      * <pre>
-     *  return formatter.print(this);
+     *  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.print(this);
+        return formatter.format(this);
     }
 
 }