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 */
62package java.time;
63
64import static java.time.temporal.ChronoField.ERA;
65import static java.time.temporal.ChronoField.YEAR;
66import static java.time.temporal.ChronoField.YEAR_OF_ERA;
67import static java.time.temporal.ChronoUnit.CENTURIES;
68import static java.time.temporal.ChronoUnit.DECADES;
69import static java.time.temporal.ChronoUnit.ERAS;
70import static java.time.temporal.ChronoUnit.MILLENNIA;
71import static java.time.temporal.ChronoUnit.YEARS;
72
73import java.io.DataInput;
74import java.io.DataOutput;
75import java.io.IOException;
76import java.io.InvalidObjectException;
77import java.io.ObjectInputStream;
78import java.io.Serializable;
79import java.time.chrono.Chronology;
80import java.time.chrono.IsoChronology;
81import java.time.format.DateTimeFormatter;
82import java.time.format.DateTimeFormatterBuilder;
83import java.time.format.DateTimeParseException;
84import java.time.format.SignStyle;
85import java.time.temporal.ChronoField;
86import java.time.temporal.ChronoUnit;
87import java.time.temporal.Temporal;
88import java.time.temporal.TemporalAccessor;
89import java.time.temporal.TemporalAdjuster;
90import java.time.temporal.TemporalAmount;
91import java.time.temporal.TemporalField;
92import java.time.temporal.TemporalQueries;
93import java.time.temporal.TemporalQuery;
94import java.time.temporal.TemporalUnit;
95import java.time.temporal.UnsupportedTemporalTypeException;
96import java.time.temporal.ValueRange;
97import 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 */
129public 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