src/share/classes/java/time/Year.java

Print this page

        

@@ -57,11 +57,11 @@
  * 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;
 
 import static java.time.temporal.ChronoField.ERA;
 import static java.time.temporal.ChronoField.YEAR;
 import static java.time.temporal.ChronoField.YEAR_OF_ERA;
 import static java.time.temporal.ChronoUnit.YEARS;

@@ -70,19 +70,27 @@
 import java.io.DataOutput;
 import java.io.IOException;
 import java.io.InvalidObjectException;
 import java.io.ObjectStreamException;
 import java.io.Serializable;
-import java.time.Clock;
-import java.time.DateTimeException;
-import java.time.LocalDate;
-import java.time.Month;
-import java.time.ZoneId;
+import java.time.chrono.Chronology;
+import java.time.chrono.IsoChronology;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
 import java.time.format.DateTimeParseException;
 import java.time.format.SignStyle;
+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.time.temporal.ValueRange;
 import java.util.Objects;
 
 /**
  * A year in the ISO-8601 calendar system, such as {@code 2007}.
  * <p>

@@ -209,12 +217,13 @@
 
     //-----------------------------------------------------------------------
     /**
      * Obtains an instance of {@code Year} from a temporal object.
      * <p>
-     * A {@code TemporalAccessor} represents some form of date and time information.
-     * This factory converts the arbitrary temporal object to an instance of {@code Year}.
+     * This obtains a year based on the specified temporal.
+     * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
+     * which this factory converts to an instance of {@code Year}.
      * <p>
      * The conversion extracts the {@link ChronoField#YEAR year} field.
      * The extraction is only permitted if the temporal object has an ISO
      * chronology, or can be converted to a {@code LocalDate}.
      * <p>

@@ -228,11 +237,11 @@
     public static Year from(TemporalAccessor temporal) {
         if (temporal instanceof Year) {
             return (Year) temporal;
         }
         try {
-            if (ISOChrono.INSTANCE.equals(Chrono.from(temporal)) == false) {
+            if (IsoChronology.INSTANCE.equals(Chronology.from(temporal)) == false) {
                 temporal = LocalDate.from(temporal);
             }
             return of(temporal.get(YEAR));
         } catch (DateTimeException ex) {
             throw new DateTimeException("Unable to obtain Year from TemporalAccessor: " + temporal.getClass(), ex);

@@ -322,22 +331,20 @@
      * This checks if this year can be queried for the specified field.
      * If false, then calling the {@link #range(TemporalField) range} and
      * {@link #get(TemporalField) get} methods will throw an exception.
      * <p>
      * If the field is a {@link ChronoField} then the query is implemented here.
-     * The {@link #isSupported(TemporalField) supported fields} will return valid
-     * values based on this date-time.
      * The supported fields are:
      * <ul>
      * <li>{@code YEAR_OF_ERA}
      * <li>{@code YEAR}
      * <li>{@code ERA}
      * </ul>
      * All other {@code ChronoField} instances will return false.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)}
+     * 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 is supported on this year, false if not

@@ -345,11 +352,11 @@
     @Override
     public boolean isSupported(TemporalField field) {
         if (field instanceof ChronoField) {
             return field == YEAR || field == YEAR_OF_ERA || field == ERA;
         }
-        return field != null && field.doIsSupported(this);
+        return field != null && field.isSupportedBy(this);
     }
 
     /**
      * Gets the range of valid values for the specified field.
      * <p>

@@ -362,11 +369,11 @@
      * The {@link #isSupported(TemporalField) supported fields} will return
      * appropriate range instances.
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
      * passing {@code this} as the argument.
      * Whether the range can be obtained is determined by the field.
      *
      * @param field  the field to query the range for, not null
      * @return the range of valid values for the field, not null

@@ -392,11 +399,11 @@
      * The {@link #isSupported(TemporalField) supported fields} will return valid
      * values based on this year.
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
      * @param field  the field to get, not null
      * @return the value for the field

@@ -419,11 +426,11 @@
      * The {@link #isSupported(TemporalField) supported fields} will return valid
      * values based on this year.
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
+     * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
      * passing {@code this} as the argument. Whether the value can be obtained,
      * and what the value represents, is determined by the field.
      *
      * @param field  the field to get, not null
      * @return the value for the field

@@ -438,11 +445,11 @@
                 case YEAR: return year;
                 case ERA: return (year < 1 ? 0 : 1);
             }
             throw new DateTimeException("Unsupported field: " + field.getName());
         }
-        return field.doGet(this);
+        return field.getFrom(this);
     }
 
     //-----------------------------------------------------------------------
     /**
      * Checks if the year is a leap year, according to the ISO proleptic

@@ -490,11 +497,11 @@
 
     //-----------------------------------------------------------------------
     /**
      * Returns an adjusted copy of this year.
      * <p>
-     * This returns a new {@code Year}, based on this one, with the year adjusted.
+     * This returns a {@code Year}, based on this one, with the year adjusted.
      * The adjustment takes place using the specified adjuster strategy object.
      * Read the documentation of the adjuster to understand what adjustment will be made.
      * <p>
      * The result of this method is obtained by invoking the
      * {@link TemporalAdjuster#adjustInto(Temporal)} method on the

@@ -513,11 +520,11 @@
     }
 
     /**
      * Returns a copy of this year with the specified field set to a new value.
      * <p>
-     * This returns a new {@code Year}, based on this one, with the value
+     * This returns a {@code Year}, based on this one, with the value
      * for the specified field changed.
      * If it is not possible to set the value, because the field is not supported or for
      * some other reason, an exception is thrown.
      * <p>
      * If the field is a {@link ChronoField} then the adjustment is implemented here.

@@ -538,11 +545,11 @@
      * then a {@code DateTimeException} will be thrown.
      * <p>
      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
-     * is obtained by invoking {@code TemporalField.doWith(Temporal, long)}
+     * is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)}
      * passing {@code this} as the argument. In this case, the field determines
      * whether and how to adjust the instant.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *

@@ -562,39 +569,85 @@
                 case YEAR: return Year.of((int) newValue);
                 case ERA: return (getLong(ERA) == newValue ? this : Year.of(1 - year));
             }
             throw new DateTimeException("Unsupported field: " + field.getName());
         }
-        return field.doWith(this, newValue);
+        return field.adjustInto(this, newValue);
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a copy of this year with the specified period added.
+     * Returns a copy of this year with the specified amount added.
+     * <p>
+     * This returns a {@code Year}, based on this one, with the specified amount added.
+     * The amount is typically {@link Period} but may be any other type implementing
+     * the {@link TemporalAmount} interface.
      * <p>
-     * This method returns a new year based on this year with the specified period added.
-     * The adder is typically {@link java.time.Period} but may be any other type implementing
-     * the {@link TemporalAdder} interface.
-     * The calculation is delegated to the specified adjuster, which typically calls
-     * back to {@link #plus(long, TemporalUnit)}.
+     * The calculation is delegated to the amount object by calling
+     * {@link TemporalAmount#addTo(Temporal)}. The amount implementation is free
+     * to implement the addition in any way it wishes, however it typically
+     * calls back to {@link #plus(long, TemporalUnit)}. Consult the documentation
+     * of the amount implementation to determine if it can be successfully added.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param adder  the adder to use, not null
+     * @param amountToAdd  the amount to add, not null
      * @return a {@code Year} based on this year with the addition made, not null
      * @throws DateTimeException if the addition cannot be made
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public Year plus(TemporalAdder adder) {
-        return (Year) adder.addTo(this);
+    public Year plus(TemporalAmount amountToAdd) {
+        return (Year) amountToAdd.addTo(this);
     }
 
     /**
-     * {@inheritDoc}
-     * @throws DateTimeException {@inheritDoc}
-     * @throws ArithmeticException {@inheritDoc}
+     * Returns a copy of this year with the specified amount added.
+     * <p>
+     * This returns a {@code Year}, based on this one, with the amount
+     * in terms of the unit added. If it is not possible to add the amount, because the
+     * unit is not supported or for some other reason, an exception is thrown.
+     * <p>
+     * If the field is a {@link ChronoUnit} then the addition is implemented here.
+     * The supported fields behave as follows:
+     * <ul>
+     * <li>{@code YEARS} -
+     *  Returns a {@code Year} with the specified number of years added.
+     *  This is equivalent to {@link #plusYears(long)}.
+     * <li>{@code DECADES} -
+     *  Returns a {@code Year} with the specified number of decades added.
+     *  This is equivalent to calling {@link #plusYears(long)} with the amount
+     *  multiplied by 10.
+     * <li>{@code CENTURIES} -
+     *  Returns a {@code Year} with the specified number of centuries added.
+     *  This is equivalent to calling {@link #plusYears(long)} with the amount
+     *  multiplied by 100.
+     * <li>{@code MILLENNIA} -
+     *  Returns a {@code Year} with the specified number of millennia added.
+     *  This is equivalent to calling {@link #plusYears(long)} with the amount
+     *  multiplied by 1,000.
+     * <li>{@code ERAS} -
+     *  Returns a {@code Year} with the specified number of eras added.
+     *  Only two eras are supported so the amount must be one, zero or minus one.
+     *  If the amount is non-zero then the year is changed such that the year-of-era
+     *  is unchanged.
+     * </ul>
+     * <p>
+     * All other {@code ChronoUnit} instances will throw a {@code DateTimeException}.
+     * <p>
+     * If the field is not a {@code ChronoUnit}, then the result of this method
+     * is obtained by invoking {@code TemporalUnit.addTo(Temporal, long)}
+     * passing {@code this} as the argument. In this case, the unit determines
+     * whether and how to perform the addition.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param amountToAdd  the amount of the unit to add to the result, may be negative
+     * @param unit  the unit of the amount to add, not null
+     * @return a {@code Year} based on this year with the specified amount added, not null
+     * @throws DateTimeException if the addition cannot be made
+     * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
     public Year plus(long amountToAdd, TemporalUnit unit) {
         if (unit instanceof ChronoUnit) {
             switch ((ChronoUnit) unit) {

@@ -604,11 +657,11 @@
                 case MILLENNIA: return plusYears(Math.multiplyExact(amountToAdd, 1000));
                 case ERAS: return with(ERA, Math.addExact(getLong(ERA), amountToAdd));
             }
             throw new DateTimeException("Unsupported unit: " + unit.getName());
         }
-        return unit.doPlus(this, amountToAdd);
+        return unit.addTo(this, amountToAdd);
     }
 
     /**
      * Returns a copy of this year with the specified number of years added.
      * <p>

@@ -625,34 +678,51 @@
         return of(YEAR.checkValidIntValue(year + yearsToAdd));  // overflow safe
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a copy of this year with the specified period subtracted.
+     * Returns a copy of this year with the specified amount subtracted.
      * <p>
-     * This method returns a new year based on this year with the specified period subtracted.
-     * The subtractor is typically {@link java.time.Period} but may be any other type implementing
-     * the {@link TemporalSubtractor} interface.
-     * The calculation is delegated to the specified adjuster, which typically calls
-     * back to {@link #minus(long, TemporalUnit)}.
+     * This returns a {@code Year}, based on this one, with the specified amount subtracted.
+     * The amount is typically {@link Period} but may be any other type implementing
+     * the {@link TemporalAmount} interface.
+     * <p>
+     * The calculation is delegated to the amount object by calling
+     * {@link TemporalAmount#subtractFrom(Temporal)}. The amount implementation is free
+     * to implement the subtraction in any way it wishes, however it typically
+     * calls back to {@link #minus(long, TemporalUnit)}. Consult the documentation
+     * of the amount implementation to determine if it can be successfully subtracted.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param subtractor  the subtractor to use, not null
+     * @param amountToSubtract  the amount to subtract, not null
      * @return a {@code Year} based on this year with the subtraction made, not null
      * @throws DateTimeException if the subtraction cannot be made
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public Year minus(TemporalSubtractor subtractor) {
-        return (Year) subtractor.subtractFrom(this);
+    public Year minus(TemporalAmount amountToSubtract) {
+        return (Year) amountToSubtract.subtractFrom(this);
     }
 
     /**
-     * {@inheritDoc}
-     * @throws DateTimeException {@inheritDoc}
-     * @throws ArithmeticException {@inheritDoc}
+     * Returns a copy of this year-month with the specified amount subtracted.
+     * <p>
+     * This returns a {@code YearMonth}, based on this one, with the amount
+     * in terms of the unit subtracted. If it is not possible to subtract the amount,
+     * because the unit is not supported or for some other reason, an exception is thrown.
+     * <p>
+     * This method is equivalent to {@link #plus(long, TemporalUnit)} with the amount negated.
+     * See that method for a full description of how addition, and thus subtraction, works.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param amountToSubtract  the amount of the unit to subtract from the result, may be negative
+     * @param unit  the unit of the amount to subtract, not null
+     * @return a {@code YearMonth} based on this year-month with the specified amount subtracted, not null
+     * @throws DateTimeException if the subtraction cannot be made
+     * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
     public Year minus(long amountToSubtract, TemporalUnit unit) {
         return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit));
     }

@@ -690,12 +760,12 @@
      * @throws ArithmeticException if numeric overflow occurs (defined by the query)
      */
     @SuppressWarnings("unchecked")
     @Override
     public <R> R query(TemporalQuery<R> query) {
-        if (query == Queries.chrono()) {
-            return (R) ISOChrono.INSTANCE;
+        if (query == Queries.chronology()) {
+            return (R) IsoChronology.INSTANCE;
         } else if (query == Queries.precision()) {
             return (R) YEARS;
         }
         return Temporal.super.query(query);
     }

@@ -726,11 +796,11 @@
      * @throws DateTimeException if unable to make the adjustment
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
     public Temporal adjustInto(Temporal temporal) {
-        if (Chrono.from(temporal).equals(ISOChrono.INSTANCE) == false) {
+        if (Chronology.from(temporal).equals(IsoChronology.INSTANCE) == false) {
             throw new DateTimeException("Adjustment only supported on ISO date-time");
         }
         return temporal.with(YEAR, year);
     }
 

@@ -748,18 +818,19 @@
      * The calculation returns a whole number, representing the number of
      * complete units between the two years.
      * For example, the period in decades between 2012 and 2031
      * will only be one decade as it is one year short of two decades.
      * <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, YEARS);   // this method
-     *   dateTime.plus(YEARS.between(start, end));      // use in plus/minus
+     *   // these two lines are equivalent
+     *   amount = start.periodUntil(end, YEARS);
+     *   amount = YEARS.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 YEARS}, {@code DECADES}, {@code CENTURIES},
      * {@code MILLENNIA} and {@code ERAS} are supported.
      * Other {@code ChronoUnit} values will throw an exception.

@@ -793,84 +864,80 @@
                 case MILLENNIA: return yearsUntil / 1000;
                 case ERAS: return end.getLong(ERA) - getLong(ERA);
             }
             throw new DateTimeException("Unsupported unit: " + unit.getName());
         }
-        return unit.between(this, endYear).getAmount();
+        return unit.between(this, endYear);
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a date formed from this year at the specified day-of-year.
+     * Combines this year with a day-of-year to create a {@code LocalDate}.
      * <p>
-     * This combines this year and the specified day-of-year to form a {@code LocalDate}.
-     * The day-of-year value 366 is only valid in a leap year.
+     * This returns a {@code LocalDate} formed from this year and the specified day-of-year.
      * <p>
-     * This instance is immutable and unaffected by this method call.
+     * The day-of-year value 366 is only valid in a leap year.
      *
      * @param dayOfYear  the day-of-year to use, not null
      * @return the local date formed from this year and the specified date of year, not null
-     * @throws DateTimeException if the day of year is 366 and this is not a leap year
+     * @throws DateTimeException if the day of year is zero or less, 366 or greater or equal
+     *  to 366 and this is not a leap year
      */
     public LocalDate atDay(int dayOfYear) {
         return LocalDate.ofYearDay(year, dayOfYear);
     }
 
     /**
-     * Returns a year-month formed from this year at the specified month.
+     * Combines this year with a month to create a {@code YearMonth}.
      * <p>
-     * This combines this year and the specified month to form a {@code YearMonth}.
+     * This returns a {@code YearMonth} formed from this year and the specified month.
      * All possible combinations of year and month are valid.
      * <p>
      * This method can be used as part of a chain to produce a date:
      * <pre>
      *  LocalDate date = year.atMonth(month).atDay(day);
      * </pre>
-     * <p>
-     * This instance is immutable and unaffected by this method call.
      *
      * @param month  the month-of-year to use, not null
      * @return the year-month formed from this year and the specified month, not null
      */
     public YearMonth atMonth(Month month) {
         return YearMonth.of(year, month);
     }
 
     /**
-     * Returns a year-month formed from this year at the specified month.
+     * Combines this year with a month to create a {@code YearMonth}.
      * <p>
-     * This combines this year and the specified month to form a {@code YearMonth}.
+     * This returns a {@code YearMonth} formed from this year and the specified month.
      * All possible combinations of year and month are valid.
      * <p>
      * This method can be used as part of a chain to produce a date:
      * <pre>
      *  LocalDate date = year.atMonth(month).atDay(day);
      * </pre>
-     * <p>
-     * This instance is immutable and unaffected by this method call.
      *
      * @param month  the month-of-year to use, from 1 (January) to 12 (December)
      * @return the year-month formed from this year and the specified month, not null
+     * @throws DateTimeException if the month is invalid
      */
     public YearMonth atMonth(int month) {
         return YearMonth.of(year, month);
     }
 
     /**
-     * Returns a date formed from this year at the specified month-day.
+     * Combines this year with a month-day to create a {@code LocalDate}.
      * <p>
-     * This combines this year and the specified month-day to form a {@code LocalDate}.
-     * The month-day value of February 29th is only valid in a leap year.
+     * This returns a {@code LocalDate} formed from this year and the specified month-day.
      * <p>
-     * This instance is immutable and unaffected by this method call.
+     * A month-day of February 29th will be adjusted to February 28th in the resulting
+     * date if the year is not a leap year.
      *
      * @param monthDay  the month-day to use, not null
      * @return the local date formed from this year and the specified month-day, not null
-     * @throws DateTimeException if the month-day is February 29th and this is not a leap year
      */
     public LocalDate atMonthDay(MonthDay monthDay) {
-        return LocalDate.of(year, monthDay.getMonth(), monthDay.getDayOfMonth());
+        return monthDay.atYear(year);
     }
 
     //-----------------------------------------------------------------------
     /**
      * Compares this year to another year.

@@ -879,10 +946,11 @@
      * It is "consistent with equals", as defined by {@link Comparable}.
      *
      * @param other  the other year to compare to, not null
      * @return the comparator value, negative if less, positive if greater
      */
+    @Override
     public int compareTo(Year other) {
         return year - other.year;
     }
 
     /**

@@ -948,27 +1016,27 @@
 
     /**
      * Outputs this year as a {@code String} using the formatter.
      * <p>
      * This year will be passed to the formatter
-     * {@link DateTimeFormatter#print(TemporalAccessor) print method}.
+     * {@link DateTimeFormatter#format(TemporalAccessor) format method}.
      *
      * @param formatter  the formatter to use, not null
      * @return the formatted year string, not null
      * @throws DateTimeException if an error occurs during printing
      */
     public String toString(DateTimeFormatter formatter) {
         Objects.requireNonNull(formatter, "formatter");
-        return formatter.print(this);
+        return formatter.format(this);
     }
 
     //-----------------------------------------------------------------------
     /**
      * Writes the object using a
      * <a href="../../../serialized-form.html#java.time.temporal.Ser">dedicated serialized form</a>.
      * <pre>
-     *  out.writeByte(4);  // identifies this as a Year
+     *  out.writeByte(11);  // identifies this as a Year
      *  out.writeInt(year);
      * </pre>
      *
      * @return the instance of {@code Ser}, not null
      */