Home | History | Annotate | Download | only in time
      1 /*
      2  * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
      3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      4  *
      5  * This code is free software; you can redistribute it and/or modify it
      6  * under the terms of the GNU General Public License version 2 only, as
      7  * published by the Free Software Foundation.  Oracle designates this
      8  * particular file as subject to the "Classpath" exception as provided
      9  * by Oracle in the LICENSE file that accompanied this code.
     10  *
     11  * This code is distributed in the hope that it will be useful, but WITHOUT
     12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14  * version 2 for more details (a copy is included in the LICENSE file that
     15  * accompanied this code).
     16  *
     17  * You should have received a copy of the GNU General Public License version
     18  * 2 along with this work; if not, write to the Free Software Foundation,
     19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     20  *
     21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     22  * or visit www.oracle.com if you need additional information or have any
     23  * questions.
     24  */
     25 
     26 /*
     27  * This file is available under and governed by the GNU General Public
     28  * License version 2 only, as published by the Free Software Foundation.
     29  * However, the following notice accompanied the original version of this
     30  * file:
     31  *
     32  * Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos
     33  *
     34  * All rights reserved.
     35  *
     36  * Redistribution and use in source and binary forms, with or without
     37  * modification, are permitted provided that the following conditions are met:
     38  *
     39  *  * Redistributions of source code must retain the above copyright notice,
     40  *    this list of conditions and the following disclaimer.
     41  *
     42  *  * Redistributions in binary form must reproduce the above copyright notice,
     43  *    this list of conditions and the following disclaimer in the documentation
     44  *    and/or other materials provided with the distribution.
     45  *
     46  *  * Neither the name of JSR-310 nor the names of its contributors
     47  *    may be used to endorse or promote products derived from this software
     48  *    without specific prior written permission.
     49  *
     50  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     51  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     52  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     53  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     54  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     55  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     56  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     57  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     58  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     59  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     60  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     61  */
     62 package java.time;
     63 
     64 import static java.time.temporal.ChronoField.ERA;
     65 import static java.time.temporal.ChronoField.YEAR;
     66 import static java.time.temporal.ChronoField.YEAR_OF_ERA;
     67 import static java.time.temporal.ChronoUnit.CENTURIES;
     68 import static java.time.temporal.ChronoUnit.DECADES;
     69 import static java.time.temporal.ChronoUnit.ERAS;
     70 import static java.time.temporal.ChronoUnit.MILLENNIA;
     71 import static java.time.temporal.ChronoUnit.YEARS;
     72 
     73 import java.io.DataInput;
     74 import java.io.DataOutput;
     75 import java.io.IOException;
     76 import java.io.InvalidObjectException;
     77 import java.io.ObjectInputStream;
     78 import java.io.Serializable;
     79 import java.time.chrono.Chronology;
     80 import java.time.chrono.IsoChronology;
     81 import java.time.format.DateTimeFormatter;
     82 import java.time.format.DateTimeFormatterBuilder;
     83 import java.time.format.DateTimeParseException;
     84 import java.time.format.SignStyle;
     85 import java.time.temporal.ChronoField;
     86 import java.time.temporal.ChronoUnit;
     87 import java.time.temporal.Temporal;
     88 import java.time.temporal.TemporalAccessor;
     89 import java.time.temporal.TemporalAdjuster;
     90 import java.time.temporal.TemporalAmount;
     91 import java.time.temporal.TemporalField;
     92 import java.time.temporal.TemporalQueries;
     93 import java.time.temporal.TemporalQuery;
     94 import java.time.temporal.TemporalUnit;
     95 import java.time.temporal.UnsupportedTemporalTypeException;
     96 import java.time.temporal.ValueRange;
     97 import java.util.Objects;
     98 
     99 // Android-changed: removed ValueBased paragraph.
    100 /**
    101  * A year in the ISO-8601 calendar system, such as {@code 2007}.
    102  * <p>
    103  * {@code Year} is an immutable date-time object that represents a year.
    104  * Any field that can be derived from a year can be obtained.
    105  * <p>
    106  * <b>Note that years in the ISO chronology only align with years in the
    107  * Gregorian-Julian system for modern years. Parts of Russia did not switch to the
    108  * modern Gregorian/ISO rules until 1920.
    109  * As such, historical years must be treated with caution.</b>
    110  * <p>
    111  * This class does not store or represent a month, day, time or time-zone.
    112  * For example, the value "2007" can be stored in a {@code Year}.
    113  * <p>
    114  * Years represented by this class follow the ISO-8601 standard and use
    115  * the proleptic numbering system. Year 1 is preceded by year 0, then by year -1.
    116  * <p>
    117  * The ISO-8601 calendar system is the modern civil calendar system used today
    118  * in most of the world. It is equivalent to the proleptic Gregorian calendar
    119  * system, in which today's rules for leap years are applied for all time.
    120  * For most applications written today, the ISO-8601 rules are entirely suitable.
    121  * However, any application that makes use of historical dates, and requires them
    122  * to be accurate will find the ISO-8601 approach unsuitable.
    123  *
    124  * @implSpec
    125  * This class is immutable and thread-safe.
    126  *
    127  * @since 1.8
    128  */
    129 public final class Year
    130         implements Temporal, TemporalAdjuster, Comparable<Year>, Serializable {
    131 
    132     /**
    133      * The minimum supported year, '-999,999,999'.
    134      */
    135     public static final int MIN_VALUE = -999_999_999;
    136     /**
    137      * The maximum supported year, '+999,999,999'.
    138      */
    139     public static final int MAX_VALUE = 999_999_999;
    140 
    141     /**
    142      * Serialization version.
    143      */
    144     private static final long serialVersionUID = -23038383694477807L;
    145     /**
    146      * Parser.
    147      */
    148     private static final DateTimeFormatter PARSER = new DateTimeFormatterBuilder()
    149         .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
    150         .toFormatter();
    151 
    152     /**
    153      * The year being represented.
    154      */
    155     private final int year;
    156 
    157     //-----------------------------------------------------------------------
    158     /**
    159      * Obtains the current year from the system clock in the default time-zone.
    160      * <p>
    161      * This will query the {@link Clock#systemDefaultZone() system clock} in the default
    162      * time-zone to obtain the current year.
    163      * <p>
    164      * Using this method will prevent the ability to use an alternate clock for testing
    165      * because the clock is hard-coded.
    166      *
    167      * @return the current year using the system clock and default time-zone, not null
    168      */
    169     public static Year now() {
    170         return now(Clock.systemDefaultZone());
    171     }
    172 
    173     /**
    174      * Obtains the current year from the system clock in the specified time-zone.
    175      * <p>
    176      * This will query the {@link Clock#system(ZoneId) system clock} to obtain the current year.
    177      * Specifying the time-zone avoids dependence on the default time-zone.
    178      * <p>
    179      * Using this method will prevent the ability to use an alternate clock for testing
    180      * because the clock is hard-coded.
    181      *
    182      * @param zone  the zone ID to use, not null
    183      * @return the current year using the system clock, not null
    184      */
    185     public static Year now(ZoneId zone) {
    186         return now(Clock.system(zone));
    187     }
    188 
    189     /**
    190      * Obtains the current year from the specified clock.
    191      * <p>
    192      * This will query the specified clock to obtain the current year.
    193      * Using this method allows the use of an alternate clock for testing.
    194      * The alternate clock may be introduced using {@link Clock dependency injection}.
    195      *
    196      * @param clock  the clock to use, not null
    197      * @return the current year, not null
    198      */
    199     public static Year now(Clock clock) {
    200         final LocalDate now = LocalDate.now(clock);  // called once
    201         return Year.of(now.getYear());
    202     }
    203 
    204     //-----------------------------------------------------------------------
    205     /**
    206      * Obtains an instance of {@code Year}.
    207      * <p>
    208      * This method accepts a year value from the proleptic ISO calendar system.
    209      * <p>
    210      * The year 2AD/CE is represented by 2.<br>
    211      * The year 1AD/CE is represented by 1.<br>
    212      * The year 1BC/BCE is represented by 0.<br>
    213      * The year 2BC/BCE is represented by -1.<br>
    214      *
    215      * @param isoYear  the ISO proleptic year to represent, from {@code MIN_VALUE} to {@code MAX_VALUE}
    216      * @return the year, not null
    217      * @throws DateTimeException if the field is invalid
    218      */
    219     public static Year of(int isoYear) {
    220         YEAR.checkValidValue(isoYear);
    221         return new Year(isoYear);
    222     }
    223 
    224     //-----------------------------------------------------------------------
    225     /**
    226      * Obtains an instance of {@code Year} from a temporal object.
    227      * <p>
    228      * This obtains a year based on the specified temporal.
    229      * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
    230      * which this factory converts to an instance of {@code Year}.
    231      * <p>
    232      * The conversion extracts the {@link ChronoField#YEAR year} field.
    233      * The extraction is only permitted if the temporal object has an ISO
    234      * chronology, or can be converted to a {@code LocalDate}.
    235      * <p>
    236      * This method matches the signature of the functional interface {@link TemporalQuery}
    237      * allowing it to be used as a query via method reference, {@code Year::from}.
    238      *
    239      * @param temporal  the temporal object to convert, not null
    240      * @return the year, not null
    241      * @throws DateTimeException if unable to convert to a {@code Year}
    242      */
    243     public static Year from(TemporalAccessor temporal) {
    244         if (temporal instanceof Year) {
    245             return (Year) temporal;
    246         }
    247         Objects.requireNonNull(temporal, "temporal");
    248         try {
    249             if (IsoChronology.INSTANCE.equals(Chronology.from(temporal)) == false) {
    250                 temporal = LocalDate.from(temporal);
    251             }
    252             return of(temporal.get(YEAR));
    253         } catch (DateTimeException ex) {
    254             throw new DateTimeException("Unable to obtain Year from TemporalAccessor: " +
    255                     temporal + " of type " + temporal.getClass().getName(), ex);
    256         }
    257     }
    258 
    259     //-----------------------------------------------------------------------
    260     /**
    261      * Obtains an instance of {@code Year} from a text string such as {@code 2007}.
    262      * <p>
    263      * The string must represent a valid year.
    264      * Years outside the range 0000 to 9999 must be prefixed by the plus or minus symbol.
    265      *
    266      * @param text  the text to parse such as "2007", not null
    267      * @return the parsed year, not null
    268      * @throws DateTimeParseException if the text cannot be parsed
    269      */
    270     public static Year parse(CharSequence text) {
    271         return parse(text, PARSER);
    272     }
    273 
    274     /**
    275      * Obtains an instance of {@code Year} from a text string using a specific formatter.
    276      * <p>
    277      * The text is parsed using the formatter, returning a year.
    278      *
    279      * @param text  the text to parse, not null
    280      * @param formatter  the formatter to use, not null
    281      * @return the parsed year, not null
    282      * @throws DateTimeParseException if the text cannot be parsed
    283      */
    284     public static Year parse(CharSequence text, DateTimeFormatter formatter) {
    285         Objects.requireNonNull(formatter, "formatter");
    286         return formatter.parse(text, Year::from);
    287     }
    288 
    289     //-------------------------------------------------------------------------
    290     /**
    291      * Checks if the year is a leap year, according to the ISO proleptic
    292      * calendar system rules.
    293      * <p>
    294      * This method applies the current rules for leap years across the whole time-line.
    295      * In general, a year is a leap year if it is divisible by four without
    296      * remainder. However, years divisible by 100, are not leap years, with
    297      * the exception of years divisible by 400 which are.
    298      * <p>
    299      * For example, 1904 is a leap year it is divisible by 4.
    300      * 1900 was not a leap year as it is divisible by 100, however 2000 was a
    301      * leap year as it is divisible by 400.
    302      * <p>
    303      * The calculation is proleptic - applying the same rules into the far future and far past.
    304      * This is historically inaccurate, but is correct for the ISO-8601 standard.
    305      *
    306      * @param year  the year to check
    307      * @return true if the year is leap, false otherwise
    308      */
    309     public static boolean isLeap(long year) {
    310         return ((year & 3) == 0) && ((year % 100) != 0 || (year % 400) == 0);
    311     }
    312 
    313     //-----------------------------------------------------------------------
    314     /**
    315      * Constructor.
    316      *
    317      * @param year  the year to represent
    318      */
    319     private Year(int year) {
    320         this.year = year;
    321     }
    322 
    323     //-----------------------------------------------------------------------
    324     /**
    325      * Gets the year value.
    326      * <p>
    327      * The year returned by this method is proleptic as per {@code get(YEAR)}.
    328      *
    329      * @return the year, {@code MIN_VALUE} to {@code MAX_VALUE}
    330      */
    331     public int getValue() {
    332         return year;
    333     }
    334 
    335     //-----------------------------------------------------------------------
    336     /**
    337      * Checks if the specified field is supported.
    338      * <p>
    339      * This checks if this year can be queried for the specified field.
    340      * If false, then calling the {@link #range(TemporalField) range},
    341      * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)}
    342      * methods will throw an exception.
    343      * <p>
    344      * If the field is a {@link ChronoField} then the query is implemented here.
    345      * The supported fields are:
    346      * <ul>
    347      * <li>{@code YEAR_OF_ERA}
    348      * <li>{@code YEAR}
    349      * <li>{@code ERA}
    350      * </ul>
    351      * All other {@code ChronoField} instances will return false.
    352      * <p>
    353      * If the field is not a {@code ChronoField}, then the result of this method
    354      * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
    355      * passing {@code this} as the argument.
    356      * Whether the field is supported is determined by the field.
    357      *
    358      * @param field  the field to check, null returns false
    359      * @return true if the field is supported on this year, false if not
    360      */
    361     @Override
    362     public boolean isSupported(TemporalField field) {
    363         if (field instanceof ChronoField) {
    364             return field == YEAR || field == YEAR_OF_ERA || field == ERA;
    365         }
    366         return field != null && field.isSupportedBy(this);
    367     }
    368 
    369     /**
    370      * Checks if the specified unit is supported.
    371      * <p>
    372      * This checks if the specified unit can be added to, or subtracted from, this year.
    373      * If false, then calling the {@link #plus(long, TemporalUnit)} and
    374      * {@link #minus(long, TemporalUnit) minus} methods will throw an exception.
    375      * <p>
    376      * If the unit is a {@link ChronoUnit} then the query is implemented here.
    377      * The supported units are:
    378      * <ul>
    379      * <li>{@code YEARS}
    380      * <li>{@code DECADES}
    381      * <li>{@code CENTURIES}
    382      * <li>{@code MILLENNIA}
    383      * <li>{@code ERAS}
    384      * </ul>
    385      * All other {@code ChronoUnit} instances will return false.
    386      * <p>
    387      * If the unit is not a {@code ChronoUnit}, then the result of this method
    388      * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)}
    389      * passing {@code this} as the argument.
    390      * Whether the unit is supported is determined by the unit.
    391      *
    392      * @param unit  the unit to check, null returns false
    393      * @return true if the unit can be added/subtracted, false if not
    394      */
    395     @Override
    396     public boolean isSupported(TemporalUnit unit) {
    397         if (unit instanceof ChronoUnit) {
    398             return unit == YEARS || unit == DECADES || unit == CENTURIES || unit == MILLENNIA || unit == ERAS;
    399         }
    400         return unit != null && unit.isSupportedBy(this);
    401     }
    402 
    403     //-----------------------------------------------------------------------
    404     /**
    405      * Gets the range of valid values for the specified field.
    406      * <p>
    407      * The range object expresses the minimum and maximum valid values for a field.
    408      * This year is used to enhance the accuracy of the returned range.
    409      * If it is not possible to return the range, because the field is not supported
    410      * or for some other reason, an exception is thrown.
    411      * <p>
    412      * If the field is a {@link ChronoField} then the query is implemented here.
    413      * The {@link #isSupported(TemporalField) supported fields} will return
    414      * appropriate range instances.
    415      * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
    416      * <p>
    417      * If the field is not a {@code ChronoField}, then the result of this method
    418      * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
    419      * passing {@code this} as the argument.
    420      * Whether the range can be obtained is determined by the field.
    421      *
    422      * @param field  the field to query the range for, not null
    423      * @return the range of valid values for the field, not null
    424      * @throws DateTimeException if the range for the field cannot be obtained
    425      * @throws UnsupportedTemporalTypeException if the field is not supported
    426      */
    427     @Override
    428     public ValueRange range(TemporalField field) {
    429         if (field == YEAR_OF_ERA) {
    430             return (year <= 0 ? ValueRange.of(1, MAX_VALUE + 1) : ValueRange.of(1, MAX_VALUE));
    431         }
    432         return Temporal.super.range(field);
    433     }
    434 
    435     /**
    436      * Gets the value of the specified field from this year as an {@code int}.
    437      * <p>
    438      * This queries this year for the value of the specified field.
    439      * The returned value will always be within the valid range of values for the field.
    440      * If it is not possible to return the value, because the field is not supported
    441      * or for some other reason, an exception is thrown.
    442      * <p>
    443      * If the field is a {@link ChronoField} then the query is implemented here.
    444      * The {@link #isSupported(TemporalField) supported fields} will return valid
    445      * values based on this year.
    446      * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
    447      * <p>
    448      * If the field is not a {@code ChronoField}, then the result of this method
    449      * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
    450      * passing {@code this} as the argument. Whether the value can be obtained,
    451      * and what the value represents, is determined by the field.
    452      *
    453      * @param field  the field to get, not null
    454      * @return the value for the field
    455      * @throws DateTimeException if a value for the field cannot be obtained or
    456      *         the value is outside the range of valid values for the field
    457      * @throws UnsupportedTemporalTypeException if the field is not supported or
    458      *         the range of values exceeds an {@code int}
    459      * @throws ArithmeticException if numeric overflow occurs
    460      */
    461     @Override  // override for Javadoc
    462     public int get(TemporalField field) {
    463         return range(field).checkValidIntValue(getLong(field), field);
    464     }
    465 
    466     /**
    467      * Gets the value of the specified field from this year as a {@code long}.
    468      * <p>
    469      * This queries this year for the value of the specified field.
    470      * If it is not possible to return the value, because the field is not supported
    471      * or for some other reason, an exception is thrown.
    472      * <p>
    473      * If the field is a {@link ChronoField} then the query is implemented here.
    474      * The {@link #isSupported(TemporalField) supported fields} will return valid
    475      * values based on this year.
    476      * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
    477      * <p>
    478      * If the field is not a {@code ChronoField}, then the result of this method
    479      * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
    480      * passing {@code this} as the argument. Whether the value can be obtained,
    481      * and what the value represents, is determined by the field.
    482      *
    483      * @param field  the field to get, not null
    484      * @return the value for the field
    485      * @throws DateTimeException if a value for the field cannot be obtained
    486      * @throws UnsupportedTemporalTypeException if the field is not supported
    487      * @throws ArithmeticException if numeric overflow occurs
    488      */
    489     @Override
    490     public long getLong(TemporalField field) {
    491         if (field instanceof ChronoField) {
    492             switch ((ChronoField) field) {
    493                 case YEAR_OF_ERA: return (year < 1 ? 1 - year : year);
    494                 case YEAR: return year;
    495                 case ERA: return (year < 1 ? 0 : 1);
    496             }
    497             throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
    498         }
    499         return field.getFrom(this);
    500     }
    501 
    502     //-----------------------------------------------------------------------
    503     /**
    504      * Checks if the year is a leap year, according to the ISO proleptic
    505      * calendar system rules.
    506      * <p>
    507      * This method applies the current rules for leap years across the whole time-line.
    508      * In general, a year is a leap year if it is divisible by four without
    509      * remainder. However, years divisible by 100, are not leap years, with
    510      * the exception of years divisible by 400 which are.
    511      * <p>
    512      * For example, 1904 is a leap year it is divisible by 4.
    513      * 1900 was not a leap year as it is divisible by 100, however 2000 was a
    514      * leap year as it is divisible by 400.
    515      * <p>
    516      * The calculation is proleptic - applying the same rules into the far future and far past.
    517      * This is historically inaccurate, but is correct for the ISO-8601 standard.
    518      *
    519      * @return true if the year is leap, false otherwise
    520      */
    521     public boolean isLeap() {
    522         return Year.isLeap(year);
    523     }
    524 
    525     /**
    526      * Checks if the month-day is valid for this year.
    527      * <p>
    528      * This method checks whether this year and the input month and day form
    529      * a valid date.
    530      *
    531      * @param monthDay  the month-day to validate, null returns false
    532      * @return true if the month and day are valid for this year
    533      */
    534     public boolean isValidMonthDay(MonthDay monthDay) {
    535         return monthDay != null && monthDay.isValidYear(year);
    536     }
    537 
    538     /**
    539      * Gets the length of this year in days.
    540      *
    541      * @return the length of this year in days, 365 or 366
    542      */
    543     public int length() {
    544         return isLeap() ? 366 : 365;
    545     }
    546 
    547     //-----------------------------------------------------------------------
    548     /**
    549      * Returns an adjusted copy of this year.
    550      * <p>
    551      * This returns a {@code Year}, based on this one, with the year adjusted.
    552      * The adjustment takes place using the specified adjuster strategy object.
    553      * Read the documentation of the adjuster to understand what adjustment will be made.
    554      * <p>
    555      * The result of this method is obtained by invoking the
    556      * {@link TemporalAdjuster#adjustInto(Temporal)} method on the
    557      * specified adjuster passing {@code this} as the argument.
    558      * <p>
    559      * This instance is immutable and unaffected by this method call.
    560      *
    561      * @param adjuster the adjuster to use, not null
    562      * @return a {@code Year} based on {@code this} with the adjustment made, not null
    563      * @throws DateTimeException if the adjustment cannot be made
    564      * @throws ArithmeticException if numeric overflow occurs
    565      */
    566     @Override
    567     public Year with(TemporalAdjuster adjuster) {
    568         return (Year) adjuster.adjustInto(this);
    569     }
    570 
    571     /**
    572      * Returns a copy of this year with the specified field set to a new value.
    573      * <p>
    574      * This returns a {@code Year}, based on this one, with the value
    575      * for the specified field changed.
    576      * If it is not possible to set the value, because the field is not supported or for
    577      * some other reason, an exception is thrown.
    578      * <p>
    579      * If the field is a {@link ChronoField} then the adjustment is implemented here.
    580      * The supported fields behave as follows:
    581      * <ul>
    582      * <li>{@code YEAR_OF_ERA} -
    583      *  Returns a {@code Year} with the specified year-of-era
    584      *  The era will be unchanged.
    585      * <li>{@code YEAR} -
    586      *  Returns a {@code Year} with the specified year.
    587      *  This completely replaces the date and is equivalent to {@link #of(int)}.
    588      * <li>{@code ERA} -
    589      *  Returns a {@code Year} with the specified era.
    590      *  The year-of-era will be unchanged.
    591      * </ul>
    592      * <p>
    593      * In all cases, if the new value is outside the valid range of values for the field
    594      * then a {@code DateTimeException} will be thrown.
    595      * <p>
    596      * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
    597      * <p>
    598      * If the field is not a {@code ChronoField}, then the result of this method
    599      * is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)}
    600      * passing {@code this} as the argument. In this case, the field determines
    601      * whether and how to adjust the instant.
    602      * <p>
    603      * This instance is immutable and unaffected by this method call.
    604      *
    605      * @param field  the field to set in the result, not null
    606      * @param newValue  the new value of the field in the result
    607      * @return a {@code Year} based on {@code this} with the specified field set, not null
    608      * @throws DateTimeException if the field cannot be set
    609      * @throws UnsupportedTemporalTypeException if the field is not supported
    610      * @throws ArithmeticException if numeric overflow occurs
    611      */
    612     @Override
    613     public Year with(TemporalField field, long newValue) {
    614         if (field instanceof ChronoField) {
    615             ChronoField f = (ChronoField) field;
    616             f.checkValidValue(newValue);
    617             switch (f) {
    618                 case YEAR_OF_ERA: return Year.of((int) (year < 1 ? 1 - newValue : newValue));
    619                 case YEAR: return Year.of((int) newValue);
    620                 case ERA: return (getLong(ERA) == newValue ? this : Year.of(1 - year));
    621             }
    622             throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
    623         }
    624         return field.adjustInto(this, newValue);
    625     }
    626 
    627     //-----------------------------------------------------------------------
    628     /**
    629      * Returns a copy of this year with the specified amount added.
    630      * <p>
    631      * This returns a {@code Year}, based on this one, with the specified amount added.
    632      * The amount is typically {@link Period} but may be any other type implementing
    633      * the {@link TemporalAmount} interface.
    634      * <p>
    635      * The calculation is delegated to the amount object by calling
    636      * {@link TemporalAmount#addTo(Temporal)}. The amount implementation is free
    637      * to implement the addition in any way it wishes, however it typically
    638      * calls back to {@link #plus(long, TemporalUnit)}. Consult the documentation
    639      * of the amount implementation to determine if it can be successfully added.
    640      * <p>
    641      * This instance is immutable and unaffected by this method call.
    642      *
    643      * @param amountToAdd  the amount to add, not null
    644      * @return a {@code Year} based on this year with the addition made, not null
    645      * @throws DateTimeException if the addition cannot be made
    646      * @throws ArithmeticException if numeric overflow occurs
    647      */
    648     @Override
    649     public Year plus(TemporalAmount amountToAdd) {
    650         return (Year) amountToAdd.addTo(this);
    651     }
    652 
    653     /**
    654      * Returns a copy of this year with the specified amount added.
    655      * <p>
    656      * This returns a {@code Year}, based on this one, with the amount
    657      * in terms of the unit added. If it is not possible to add the amount, because the
    658      * unit is not supported or for some other reason, an exception is thrown.
    659      * <p>
    660      * If the field is a {@link ChronoUnit} then the addition is implemented here.
    661      * The supported fields behave as follows:
    662      * <ul>
    663      * <li>{@code YEARS} -
    664      *  Returns a {@code Year} with the specified number of years added.
    665      *  This is equivalent to {@link #plusYears(long)}.
    666      * <li>{@code DECADES} -
    667      *  Returns a {@code Year} with the specified number of decades added.
    668      *  This is equivalent to calling {@link #plusYears(long)} with the amount
    669      *  multiplied by 10.
    670      * <li>{@code CENTURIES} -
    671      *  Returns a {@code Year} with the specified number of centuries added.
    672      *  This is equivalent to calling {@link #plusYears(long)} with the amount
    673      *  multiplied by 100.
    674      * <li>{@code MILLENNIA} -
    675      *  Returns a {@code Year} with the specified number of millennia added.
    676      *  This is equivalent to calling {@link #plusYears(long)} with the amount
    677      *  multiplied by 1,000.
    678      * <li>{@code ERAS} -
    679      *  Returns a {@code Year} with the specified number of eras added.
    680      *  Only two eras are supported so the amount must be one, zero or minus one.
    681      *  If the amount is non-zero then the year is changed such that the year-of-era
    682      *  is unchanged.
    683      * </ul>
    684      * <p>
    685      * All other {@code ChronoUnit} instances will throw an {@code UnsupportedTemporalTypeException}.
    686      * <p>
    687      * If the field is not a {@code ChronoUnit}, then the result of this method
    688      * is obtained by invoking {@code TemporalUnit.addTo(Temporal, long)}
    689      * passing {@code this} as the argument. In this case, the unit determines
    690      * whether and how to perform the addition.
    691      * <p>
    692      * This instance is immutable and unaffected by this method call.
    693      *
    694      * @param amountToAdd  the amount of the unit to add to the result, may be negative
    695      * @param unit  the unit of the amount to add, not null
    696      * @return a {@code Year} based on this year with the specified amount added, not null
    697      * @throws DateTimeException if the addition cannot be made
    698      * @throws UnsupportedTemporalTypeException if the unit is not supported
    699      * @throws ArithmeticException if numeric overflow occurs
    700      */
    701     @Override
    702     public Year plus(long amountToAdd, TemporalUnit unit) {
    703         if (unit instanceof ChronoUnit) {
    704             switch ((ChronoUnit) unit) {
    705                 case YEARS: return plusYears(amountToAdd);
    706                 case DECADES: return plusYears(Math.multiplyExact(amountToAdd, 10));
    707                 case CENTURIES: return plusYears(Math.multiplyExact(amountToAdd, 100));
    708                 case MILLENNIA: return plusYears(Math.multiplyExact(amountToAdd, 1000));
    709                 case ERAS: return with(ERA, Math.addExact(getLong(ERA), amountToAdd));
    710             }
    711             throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
    712         }
    713         return unit.addTo(this, amountToAdd);
    714     }
    715 
    716     /**
    717      * Returns a copy of this {@code Year} with the specified number of years added.
    718      * <p>
    719      * This instance is immutable and unaffected by this method call.
    720      *
    721      * @param yearsToAdd  the years to add, may be negative
    722      * @return a {@code Year} based on this year with the years added, not null
    723      * @throws DateTimeException if the result exceeds the supported range
    724      */
    725     public Year plusYears(long yearsToAdd) {
    726         if (yearsToAdd == 0) {
    727             return this;
    728         }
    729         return of(YEAR.checkValidIntValue(year + yearsToAdd));  // overflow safe
    730     }
    731 
    732     //-----------------------------------------------------------------------
    733     /**
    734      * Returns a copy of this year with the specified amount subtracted.
    735      * <p>
    736      * This returns a {@code Year}, based on this one, with the specified amount subtracted.
    737      * The amount is typically {@link Period} but may be any other type implementing
    738      * the {@link TemporalAmount} interface.
    739      * <p>
    740      * The calculation is delegated to the amount object by calling
    741      * {@link TemporalAmount#subtractFrom(Temporal)}. The amount implementation is free
    742      * to implement the subtraction in any way it wishes, however it typically
    743      * calls back to {@link #minus(long, TemporalUnit)}. Consult the documentation
    744      * of the amount implementation to determine if it can be successfully subtracted.
    745      * <p>
    746      * This instance is immutable and unaffected by this method call.
    747      *
    748      * @param amountToSubtract  the amount to subtract, not null
    749      * @return a {@code Year} based on this year with the subtraction made, not null
    750      * @throws DateTimeException if the subtraction cannot be made
    751      * @throws ArithmeticException if numeric overflow occurs
    752      */
    753     @Override
    754     public Year minus(TemporalAmount amountToSubtract) {
    755         return (Year) amountToSubtract.subtractFrom(this);
    756     }
    757 
    758     /**
    759      * Returns a copy of this year with the specified amount subtracted.
    760      * <p>
    761      * This returns a {@code Year}, based on this one, with the amount
    762      * in terms of the unit subtracted. If it is not possible to subtract the amount,
    763      * because the unit is not supported or for some other reason, an exception is thrown.
    764      * <p>
    765      * This method is equivalent to {@link #plus(long, TemporalUnit)} with the amount negated.
    766      * See that method for a full description of how addition, and thus subtraction, works.
    767      * <p>
    768      * This instance is immutable and unaffected by this method call.
    769      *
    770      * @param amountToSubtract  the amount of the unit to subtract from the result, may be negative
    771      * @param unit  the unit of the amount to subtract, not null
    772      * @return a {@code Year} based on this year with the specified amount subtracted, not null
    773      * @throws DateTimeException if the subtraction cannot be made
    774      * @throws UnsupportedTemporalTypeException if the unit is not supported
    775      * @throws ArithmeticException if numeric overflow occurs
    776      */
    777     @Override
    778     public Year minus(long amountToSubtract, TemporalUnit unit) {
    779         return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit));
    780     }
    781 
    782     /**
    783      * Returns a copy of this {@code Year} with the specified number of years subtracted.
    784      * <p>
    785      * This instance is immutable and unaffected by this method call.
    786      *
    787      * @param yearsToSubtract  the years to subtract, may be negative
    788      * @return a {@code Year} based on this year with the year subtracted, not null
    789      * @throws DateTimeException if the result exceeds the supported range
    790      */
    791     public Year minusYears(long yearsToSubtract) {
    792         return (yearsToSubtract == Long.MIN_VALUE ? plusYears(Long.MAX_VALUE).plusYears(1) : plusYears(-yearsToSubtract));
    793     }
    794 
    795     //-----------------------------------------------------------------------
    796     /**
    797      * Queries this year using the specified query.
    798      * <p>
    799      * This queries this year using the specified query strategy object.
    800      * The {@code TemporalQuery} object defines the logic to be used to
    801      * obtain the result. Read the documentation of the query to understand
    802      * what the result of this method will be.
    803      * <p>
    804      * The result of this method is obtained by invoking the
    805      * {@link TemporalQuery#queryFrom(TemporalAccessor)} method on the
    806      * specified query passing {@code this} as the argument.
    807      *
    808      * @param <R> the type of the result
    809      * @param query  the query to invoke, not null
    810      * @return the query result, null may be returned (defined by the query)
    811      * @throws DateTimeException if unable to query (defined by the query)
    812      * @throws ArithmeticException if numeric overflow occurs (defined by the query)
    813      */
    814     @SuppressWarnings("unchecked")
    815     @Override
    816     public <R> R query(TemporalQuery<R> query) {
    817         if (query == TemporalQueries.chronology()) {
    818             return (R) IsoChronology.INSTANCE;
    819         } else if (query == TemporalQueries.precision()) {
    820             return (R) YEARS;
    821         }
    822         return Temporal.super.query(query);
    823     }
    824 
    825     /**
    826      * Adjusts the specified temporal object to have this year.
    827      * <p>
    828      * This returns a temporal object of the same observable type as the input
    829      * with the year changed to be the same as this.
    830      * <p>
    831      * The adjustment is equivalent to using {@link Temporal#with(TemporalField, long)}
    832      * passing {@link ChronoField#YEAR} as the field.
    833      * If the specified temporal object does not use the ISO calendar system then
    834      * a {@code DateTimeException} is thrown.
    835      * <p>
    836      * In most cases, it is clearer to reverse the calling pattern by using
    837      * {@link Temporal#with(TemporalAdjuster)}:
    838      * <pre>
    839      *   // these two lines are equivalent, but the second approach is recommended
    840      *   temporal = thisYear.adjustInto(temporal);
    841      *   temporal = temporal.with(thisYear);
    842      * </pre>
    843      * <p>
    844      * This instance is immutable and unaffected by this method call.
    845      *
    846      * @param temporal  the target object to be adjusted, not null
    847      * @return the adjusted object, not null
    848      * @throws DateTimeException if unable to make the adjustment
    849      * @throws ArithmeticException if numeric overflow occurs
    850      */
    851     @Override
    852     public Temporal adjustInto(Temporal temporal) {
    853         if (Chronology.from(temporal).equals(IsoChronology.INSTANCE) == false) {
    854             throw new DateTimeException("Adjustment only supported on ISO date-time");
    855         }
    856         return temporal.with(YEAR, year);
    857     }
    858 
    859     /**
    860      * Calculates the amount of time until another year in terms of the specified unit.
    861      * <p>
    862      * This calculates the amount of time between two {@code Year}
    863      * objects in terms of a single {@code TemporalUnit}.
    864      * The start and end points are {@code this} and the specified year.
    865      * The result will be negative if the end is before the start.
    866      * The {@code Temporal} passed to this method is converted to a
    867      * {@code Year} using {@link #from(TemporalAccessor)}.
    868      * For example, the amount in decades between two year can be calculated
    869      * using {@code startYear.until(endYear, DECADES)}.
    870      * <p>
    871      * The calculation returns a whole number, representing the number of
    872      * complete units between the two years.
    873      * For example, the amount in decades between 2012 and 2031
    874      * will only be one decade as it is one year short of two decades.
    875      * <p>
    876      * There are two equivalent ways of using this method.
    877      * The first is to invoke this method.
    878      * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}:
    879      * <pre>
    880      *   // these two lines are equivalent
    881      *   amount = start.until(end, YEARS);
    882      *   amount = YEARS.between(start, end);
    883      * </pre>
    884      * The choice should be made based on which makes the code more readable.
    885      * <p>
    886      * The calculation is implemented in this method for {@link ChronoUnit}.
    887      * The units {@code YEARS}, {@code DECADES}, {@code CENTURIES},
    888      * {@code MILLENNIA} and {@code ERAS} are supported.
    889      * Other {@code ChronoUnit} values will throw an exception.
    890      * <p>
    891      * If the unit is not a {@code ChronoUnit}, then the result of this method
    892      * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)}
    893      * passing {@code this} as the first argument and the converted input temporal
    894      * as the second argument.
    895      * <p>
    896      * This instance is immutable and unaffected by this method call.
    897      *
    898      * @param endExclusive  the end date, exclusive, which is converted to a {@code Year}, not null
    899      * @param unit  the unit to measure the amount in, not null
    900      * @return the amount of time between this year and the end year
    901      * @throws DateTimeException if the amount cannot be calculated, or the end
    902      *  temporal cannot be converted to a {@code Year}
    903      * @throws UnsupportedTemporalTypeException if the unit is not supported
    904      * @throws ArithmeticException if numeric overflow occurs
    905      */
    906     @Override
    907     public long until(Temporal endExclusive, TemporalUnit unit) {
    908         Year end = Year.from(endExclusive);
    909         if (unit instanceof ChronoUnit) {
    910             long yearsUntil = ((long) end.year) - year;  // no overflow
    911             switch ((ChronoUnit) unit) {
    912                 case YEARS: return yearsUntil;
    913                 case DECADES: return yearsUntil / 10;
    914                 case CENTURIES: return yearsUntil / 100;
    915                 case MILLENNIA: return yearsUntil / 1000;
    916                 case ERAS: return end.getLong(ERA) - getLong(ERA);
    917             }
    918             throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
    919         }
    920         return unit.between(this, end);
    921     }
    922 
    923     /**
    924      * Formats this year using the specified formatter.
    925      * <p>
    926      * This year will be passed to the formatter to produce a string.
    927      *
    928      * @param formatter  the formatter to use, not null
    929      * @return the formatted year string, not null
    930      * @throws DateTimeException if an error occurs during printing
    931      */
    932     public String format(DateTimeFormatter formatter) {
    933         Objects.requireNonNull(formatter, "formatter");
    934         return formatter.format(this);
    935     }
    936 
    937     //-----------------------------------------------------------------------
    938     /**
    939      * Combines this year with a day-of-year to create a {@code LocalDate}.
    940      * <p>
    941      * This returns a {@code LocalDate} formed from this year and the specified day-of-year.
    942      * <p>
    943      * The day-of-year value 366 is only valid in a leap year.
    944      *
    945      * @param dayOfYear  the day-of-year to use, from 1 to 365-366
    946      * @return the local date formed from this year and the specified date of year, not null
    947      * @throws DateTimeException if the day of year is zero or less, 366 or greater or equal
    948      *  to 366 and this is not a leap year
    949      */
    950     public LocalDate atDay(int dayOfYear) {
    951         return LocalDate.ofYearDay(year, dayOfYear);
    952     }
    953 
    954     /**
    955      * Combines this year with a month to create a {@code YearMonth}.
    956      * <p>
    957      * This returns a {@code YearMonth} formed from this year and the specified month.
    958      * All possible combinations of year and month are valid.
    959      * <p>
    960      * This method can be used as part of a chain to produce a date:
    961      * <pre>
    962      *  LocalDate date = year.atMonth(month).atDay(day);
    963      * </pre>
    964      *
    965      * @param month  the month-of-year to use, not null
    966      * @return the year-month formed from this year and the specified month, not null
    967      */
    968     public YearMonth atMonth(Month month) {
    969         return YearMonth.of(year, month);
    970     }
    971 
    972     /**
    973      * Combines this year with a month to create a {@code YearMonth}.
    974      * <p>
    975      * This returns a {@code YearMonth} formed from this year and the specified month.
    976      * All possible combinations of year and month are valid.
    977      * <p>
    978      * This method can be used as part of a chain to produce a date:
    979      * <pre>
    980      *  LocalDate date = year.atMonth(month).atDay(day);
    981      * </pre>
    982      *
    983      * @param month  the month-of-year to use, from 1 (January) to 12 (December)
    984      * @return the year-month formed from this year and the specified month, not null
    985      * @throws DateTimeException if the month is invalid
    986      */
    987     public YearMonth atMonth(int month) {
    988         return YearMonth.of(year, month);
    989     }
    990 
    991     /**
    992      * Combines this year with a month-day to create a {@code LocalDate}.
    993      * <p>
    994      * This returns a {@code LocalDate} formed from this year and the specified month-day.
    995      * <p>
    996      * A month-day of February 29th will be adjusted to February 28th in the resulting
    997      * date if the year is not a leap year.
    998      *
    999      * @param monthDay  the month-day to use, not null
   1000      * @return the local date formed from this year and the specified month-day, not null
   1001      */
   1002     public LocalDate atMonthDay(MonthDay monthDay) {
   1003         return monthDay.atYear(year);
   1004     }
   1005 
   1006     //-----------------------------------------------------------------------
   1007     /**
   1008      * Compares this year to another year.
   1009      * <p>
   1010      * The comparison is based on the value of the year.
   1011      * It is "consistent with equals", as defined by {@link Comparable}.
   1012      *
   1013      * @param other  the other year to compare to, not null
   1014      * @return the comparator value, negative if less, positive if greater
   1015      */
   1016     @Override
   1017     public int compareTo(Year other) {
   1018         return year - other.year;
   1019     }
   1020 
   1021     /**
   1022      * Checks if this year is after the specified year.
   1023      *
   1024      * @param other  the other year to compare to, not null
   1025      * @return true if this is after the specified year
   1026      */
   1027     public boolean isAfter(Year other) {
   1028         return year > other.year;
   1029     }
   1030 
   1031     /**
   1032      * Checks if this year is before the specified year.
   1033      *
   1034      * @param other  the other year to compare to, not null
   1035      * @return true if this point is before the specified year
   1036      */
   1037     public boolean isBefore(Year other) {
   1038         return year < other.year;
   1039     }
   1040 
   1041     //-----------------------------------------------------------------------
   1042     /**
   1043      * Checks if this year is equal to another year.
   1044      * <p>
   1045      * The comparison is based on the time-line position of the years.
   1046      *
   1047      * @param obj  the object to check, null returns false
   1048      * @return true if this is equal to the other year
   1049      */
   1050     @Override
   1051     public boolean equals(Object obj) {
   1052         if (this == obj) {
   1053             return true;
   1054         }
   1055         if (obj instanceof Year) {
   1056             return year == ((Year) obj).year;
   1057         }
   1058         return false;
   1059     }
   1060 
   1061     /**
   1062      * A hash code for this year.
   1063      *
   1064      * @return a suitable hash code
   1065      */
   1066     @Override
   1067     public int hashCode() {
   1068         return year;
   1069     }
   1070 
   1071     //-----------------------------------------------------------------------
   1072     /**
   1073      * Outputs this year as a {@code String}.
   1074      *
   1075      * @return a string representation of this year, not null
   1076      */
   1077     @Override
   1078     public String toString() {
   1079         return Integer.toString(year);
   1080     }
   1081 
   1082     //-----------------------------------------------------------------------
   1083     /**
   1084      * Writes the object using a
   1085      * <a href="../../serialized-form.html#java.time.Ser">dedicated serialized form</a>.
   1086      * @serialData
   1087      * <pre>
   1088      *  out.writeByte(11);  // identifies a Year
   1089      *  out.writeInt(year);
   1090      * </pre>
   1091      *
   1092      * @return the instance of {@code Ser}, not null
   1093      */
   1094     private Object writeReplace() {
   1095         return new Ser(Ser.YEAR_TYPE, this);
   1096     }
   1097 
   1098     /**
   1099      * Defend against malicious streams.
   1100      *
   1101      * @param s the stream to read
   1102      * @throws InvalidObjectException always
   1103      */
   1104     private void readObject(ObjectInputStream s) throws InvalidObjectException {
   1105         throw new InvalidObjectException("Deserialization via serialization delegate");
   1106     }
   1107 
   1108     void writeExternal(DataOutput out) throws IOException {
   1109         out.writeInt(year);
   1110     }
   1111 
   1112     static Year readExternal(DataInput in) throws IOException {
   1113         return Year.of(in.readInt());
   1114     }
   1115 
   1116 }
   1117