Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/time/YearMonth.java
38829 views
/*1* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425/*26* This file is available under and governed by the GNU General Public27* License version 2 only, as published by the Free Software Foundation.28* However, the following notice accompanied the original version of this29* file:30*31* Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos32*33* All rights reserved.34*35* Redistribution and use in source and binary forms, with or without36* modification, are permitted provided that the following conditions are met:37*38* * Redistributions of source code must retain the above copyright notice,39* this list of conditions and the following disclaimer.40*41* * Redistributions in binary form must reproduce the above copyright notice,42* this list of conditions and the following disclaimer in the documentation43* and/or other materials provided with the distribution.44*45* * Neither the name of JSR-310 nor the names of its contributors46* may be used to endorse or promote products derived from this software47* without specific prior written permission.48*49* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS50* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT51* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR52* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR53* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,54* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,55* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR56* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF57* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING58* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS59* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.60*/61package java.time;6263import static java.time.temporal.ChronoField.ERA;64import static java.time.temporal.ChronoField.MONTH_OF_YEAR;65import static java.time.temporal.ChronoField.PROLEPTIC_MONTH;66import static java.time.temporal.ChronoField.YEAR;67import static java.time.temporal.ChronoField.YEAR_OF_ERA;68import static java.time.temporal.ChronoUnit.CENTURIES;69import static java.time.temporal.ChronoUnit.DECADES;70import static java.time.temporal.ChronoUnit.ERAS;71import static java.time.temporal.ChronoUnit.MILLENNIA;72import static java.time.temporal.ChronoUnit.MONTHS;73import static java.time.temporal.ChronoUnit.YEARS;7475import java.io.DataInput;76import java.io.DataOutput;77import java.io.IOException;78import java.io.InvalidObjectException;79import java.io.ObjectInputStream;80import java.io.Serializable;81import java.time.chrono.Chronology;82import java.time.chrono.IsoChronology;83import java.time.format.DateTimeFormatter;84import java.time.format.DateTimeFormatterBuilder;85import java.time.format.DateTimeParseException;86import java.time.format.SignStyle;87import java.time.temporal.ChronoField;88import java.time.temporal.ChronoUnit;89import java.time.temporal.Temporal;90import java.time.temporal.TemporalAccessor;91import java.time.temporal.TemporalAdjuster;92import java.time.temporal.TemporalAmount;93import java.time.temporal.TemporalField;94import java.time.temporal.TemporalQueries;95import java.time.temporal.TemporalQuery;96import java.time.temporal.TemporalUnit;97import java.time.temporal.UnsupportedTemporalTypeException;98import java.time.temporal.ValueRange;99import java.util.Objects;100101/**102* A year-month in the ISO-8601 calendar system, such as {@code 2007-12}.103* <p>104* {@code YearMonth} is an immutable date-time object that represents the combination105* of a year and month. Any field that can be derived from a year and month, such as106* quarter-of-year, can be obtained.107* <p>108* This class does not store or represent a day, time or time-zone.109* For example, the value "October 2007" can be stored in a {@code YearMonth}.110* <p>111* The ISO-8601 calendar system is the modern civil calendar system used today112* in most of the world. It is equivalent to the proleptic Gregorian calendar113* system, in which today's rules for leap years are applied for all time.114* For most applications written today, the ISO-8601 rules are entirely suitable.115* However, any application that makes use of historical dates, and requires them116* to be accurate will find the ISO-8601 approach unsuitable.117*118* <p>119* This is a <a href="{@docRoot}/java/lang/doc-files/ValueBased.html">value-based</a>120* class; use of identity-sensitive operations (including reference equality121* ({@code ==}), identity hash code, or synchronization) on instances of122* {@code YearMonth} may have unpredictable results and should be avoided.123* The {@code equals} method should be used for comparisons.124*125* @implSpec126* This class is immutable and thread-safe.127*128* @since 1.8129*/130public final class YearMonth131implements Temporal, TemporalAdjuster, Comparable<YearMonth>, Serializable {132133/**134* Serialization version.135*/136private static final long serialVersionUID = 4183400860270640070L;137/**138* Parser.139*/140private static final DateTimeFormatter PARSER = new DateTimeFormatterBuilder()141.appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)142.appendLiteral('-')143.appendValue(MONTH_OF_YEAR, 2)144.toFormatter();145146/**147* The year.148*/149private final int year;150/**151* The month-of-year, not null.152*/153private final int month;154155//-----------------------------------------------------------------------156/**157* Obtains the current year-month from the system clock in the default time-zone.158* <p>159* This will query the {@link Clock#systemDefaultZone() system clock} in the default160* time-zone to obtain the current year-month.161* <p>162* Using this method will prevent the ability to use an alternate clock for testing163* because the clock is hard-coded.164*165* @return the current year-month using the system clock and default time-zone, not null166*/167public static YearMonth now() {168return now(Clock.systemDefaultZone());169}170171/**172* Obtains the current year-month from the system clock in the specified time-zone.173* <p>174* This will query the {@link Clock#system(ZoneId) system clock} to obtain the current year-month.175* Specifying the time-zone avoids dependence on the default time-zone.176* <p>177* Using this method will prevent the ability to use an alternate clock for testing178* because the clock is hard-coded.179*180* @param zone the zone ID to use, not null181* @return the current year-month using the system clock, not null182*/183public static YearMonth now(ZoneId zone) {184return now(Clock.system(zone));185}186187/**188* Obtains the current year-month from the specified clock.189* <p>190* This will query the specified clock to obtain the current year-month.191* Using this method allows the use of an alternate clock for testing.192* The alternate clock may be introduced using {@link Clock dependency injection}.193*194* @param clock the clock to use, not null195* @return the current year-month, not null196*/197public static YearMonth now(Clock clock) {198final LocalDate now = LocalDate.now(clock); // called once199return YearMonth.of(now.getYear(), now.getMonth());200}201202//-----------------------------------------------------------------------203/**204* Obtains an instance of {@code YearMonth} from a year and month.205*206* @param year the year to represent, from MIN_YEAR to MAX_YEAR207* @param month the month-of-year to represent, not null208* @return the year-month, not null209* @throws DateTimeException if the year value is invalid210*/211public static YearMonth of(int year, Month month) {212Objects.requireNonNull(month, "month");213return of(year, month.getValue());214}215216/**217* Obtains an instance of {@code YearMonth} from a year and month.218*219* @param year the year to represent, from MIN_YEAR to MAX_YEAR220* @param month the month-of-year to represent, from 1 (January) to 12 (December)221* @return the year-month, not null222* @throws DateTimeException if either field value is invalid223*/224public static YearMonth of(int year, int month) {225YEAR.checkValidValue(year);226MONTH_OF_YEAR.checkValidValue(month);227return new YearMonth(year, month);228}229230//-----------------------------------------------------------------------231/**232* Obtains an instance of {@code YearMonth} from a temporal object.233* <p>234* This obtains a year-month based on the specified temporal.235* A {@code TemporalAccessor} represents an arbitrary set of date and time information,236* which this factory converts to an instance of {@code YearMonth}.237* <p>238* The conversion extracts the {@link ChronoField#YEAR YEAR} and239* {@link ChronoField#MONTH_OF_YEAR MONTH_OF_YEAR} fields.240* The extraction is only permitted if the temporal object has an ISO241* chronology, or can be converted to a {@code LocalDate}.242* <p>243* This method matches the signature of the functional interface {@link TemporalQuery}244* allowing it to be used as a query via method reference, {@code YearMonth::from}.245*246* @param temporal the temporal object to convert, not null247* @return the year-month, not null248* @throws DateTimeException if unable to convert to a {@code YearMonth}249*/250public static YearMonth from(TemporalAccessor temporal) {251if (temporal instanceof YearMonth) {252return (YearMonth) temporal;253}254Objects.requireNonNull(temporal, "temporal");255try {256if (IsoChronology.INSTANCE.equals(Chronology.from(temporal)) == false) {257temporal = LocalDate.from(temporal);258}259return of(temporal.get(YEAR), temporal.get(MONTH_OF_YEAR));260} catch (DateTimeException ex) {261throw new DateTimeException("Unable to obtain YearMonth from TemporalAccessor: " +262temporal + " of type " + temporal.getClass().getName(), ex);263}264}265266//-----------------------------------------------------------------------267/**268* Obtains an instance of {@code YearMonth} from a text string such as {@code 2007-12}.269* <p>270* The string must represent a valid year-month.271* The format must be {@code uuuu-MM}.272* Years outside the range 0000 to 9999 must be prefixed by the plus or minus symbol.273*274* @param text the text to parse such as "2007-12", not null275* @return the parsed year-month, not null276* @throws DateTimeParseException if the text cannot be parsed277*/278public static YearMonth parse(CharSequence text) {279return parse(text, PARSER);280}281282/**283* Obtains an instance of {@code YearMonth} from a text string using a specific formatter.284* <p>285* The text is parsed using the formatter, returning a year-month.286*287* @param text the text to parse, not null288* @param formatter the formatter to use, not null289* @return the parsed year-month, not null290* @throws DateTimeParseException if the text cannot be parsed291*/292public static YearMonth parse(CharSequence text, DateTimeFormatter formatter) {293Objects.requireNonNull(formatter, "formatter");294return formatter.parse(text, YearMonth::from);295}296297//-----------------------------------------------------------------------298/**299* Constructor.300*301* @param year the year to represent, validated from MIN_YEAR to MAX_YEAR302* @param month the month-of-year to represent, validated from 1 (January) to 12 (December)303*/304private YearMonth(int year, int month) {305this.year = year;306this.month = month;307}308309/**310* Returns a copy of this year-month with the new year and month, checking311* to see if a new object is in fact required.312*313* @param newYear the year to represent, validated from MIN_YEAR to MAX_YEAR314* @param newMonth the month-of-year to represent, validated not null315* @return the year-month, not null316*/317private YearMonth with(int newYear, int newMonth) {318if (year == newYear && month == newMonth) {319return this;320}321return new YearMonth(newYear, newMonth);322}323324//-----------------------------------------------------------------------325/**326* Checks if the specified field is supported.327* <p>328* This checks if this year-month can be queried for the specified field.329* If false, then calling the {@link #range(TemporalField) range},330* {@link #get(TemporalField) get} and {@link #with(TemporalField, long)}331* methods will throw an exception.332* <p>333* If the field is a {@link ChronoField} then the query is implemented here.334* The supported fields are:335* <ul>336* <li>{@code MONTH_OF_YEAR}337* <li>{@code PROLEPTIC_MONTH}338* <li>{@code YEAR_OF_ERA}339* <li>{@code YEAR}340* <li>{@code ERA}341* </ul>342* All other {@code ChronoField} instances will return false.343* <p>344* If the field is not a {@code ChronoField}, then the result of this method345* is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}346* passing {@code this} as the argument.347* Whether the field is supported is determined by the field.348*349* @param field the field to check, null returns false350* @return true if the field is supported on this year-month, false if not351*/352@Override353public boolean isSupported(TemporalField field) {354if (field instanceof ChronoField) {355return field == YEAR || field == MONTH_OF_YEAR ||356field == PROLEPTIC_MONTH || field == YEAR_OF_ERA || field == ERA;357}358return field != null && field.isSupportedBy(this);359}360361/**362* Checks if the specified unit is supported.363* <p>364* This checks if the specified unit can be added to, or subtracted from, this year-month.365* If false, then calling the {@link #plus(long, TemporalUnit)} and366* {@link #minus(long, TemporalUnit) minus} methods will throw an exception.367* <p>368* If the unit is a {@link ChronoUnit} then the query is implemented here.369* The supported units are:370* <ul>371* <li>{@code MONTHS}372* <li>{@code YEARS}373* <li>{@code DECADES}374* <li>{@code CENTURIES}375* <li>{@code MILLENNIA}376* <li>{@code ERAS}377* </ul>378* All other {@code ChronoUnit} instances will return false.379* <p>380* If the unit is not a {@code ChronoUnit}, then the result of this method381* is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)}382* passing {@code this} as the argument.383* Whether the unit is supported is determined by the unit.384*385* @param unit the unit to check, null returns false386* @return true if the unit can be added/subtracted, false if not387*/388@Override389public boolean isSupported(TemporalUnit unit) {390if (unit instanceof ChronoUnit) {391return unit == MONTHS || unit == YEARS || unit == DECADES || unit == CENTURIES || unit == MILLENNIA || unit == ERAS;392}393return unit != null && unit.isSupportedBy(this);394}395396//-----------------------------------------------------------------------397/**398* Gets the range of valid values for the specified field.399* <p>400* The range object expresses the minimum and maximum valid values for a field.401* This year-month is used to enhance the accuracy of the returned range.402* If it is not possible to return the range, because the field is not supported403* or for some other reason, an exception is thrown.404* <p>405* If the field is a {@link ChronoField} then the query is implemented here.406* The {@link #isSupported(TemporalField) supported fields} will return407* appropriate range instances.408* All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.409* <p>410* If the field is not a {@code ChronoField}, then the result of this method411* is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}412* passing {@code this} as the argument.413* Whether the range can be obtained is determined by the field.414*415* @param field the field to query the range for, not null416* @return the range of valid values for the field, not null417* @throws DateTimeException if the range for the field cannot be obtained418* @throws UnsupportedTemporalTypeException if the field is not supported419*/420@Override421public ValueRange range(TemporalField field) {422if (field == YEAR_OF_ERA) {423return (getYear() <= 0 ? ValueRange.of(1, Year.MAX_VALUE + 1) : ValueRange.of(1, Year.MAX_VALUE));424}425return Temporal.super.range(field);426}427428/**429* Gets the value of the specified field from this year-month as an {@code int}.430* <p>431* This queries this year-month for the value of the specified field.432* The returned value will always be within the valid range of values for the field.433* If it is not possible to return the value, because the field is not supported434* or for some other reason, an exception is thrown.435* <p>436* If the field is a {@link ChronoField} then the query is implemented here.437* The {@link #isSupported(TemporalField) supported fields} will return valid438* values based on this year-month, except {@code PROLEPTIC_MONTH} which is too439* large to fit in an {@code int} and throw a {@code DateTimeException}.440* All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.441* <p>442* If the field is not a {@code ChronoField}, then the result of this method443* is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}444* passing {@code this} as the argument. Whether the value can be obtained,445* and what the value represents, is determined by the field.446*447* @param field the field to get, not null448* @return the value for the field449* @throws DateTimeException if a value for the field cannot be obtained or450* the value is outside the range of valid values for the field451* @throws UnsupportedTemporalTypeException if the field is not supported or452* the range of values exceeds an {@code int}453* @throws ArithmeticException if numeric overflow occurs454*/455@Override // override for Javadoc456public int get(TemporalField field) {457return range(field).checkValidIntValue(getLong(field), field);458}459460/**461* Gets the value of the specified field from this year-month as a {@code long}.462* <p>463* This queries this year-month for the value of the specified field.464* If it is not possible to return the value, because the field is not supported465* or for some other reason, an exception is thrown.466* <p>467* If the field is a {@link ChronoField} then the query is implemented here.468* The {@link #isSupported(TemporalField) supported fields} will return valid469* values based on this year-month.470* All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.471* <p>472* If the field is not a {@code ChronoField}, then the result of this method473* is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}474* passing {@code this} as the argument. Whether the value can be obtained,475* and what the value represents, is determined by the field.476*477* @param field the field to get, not null478* @return the value for the field479* @throws DateTimeException if a value for the field cannot be obtained480* @throws UnsupportedTemporalTypeException if the field is not supported481* @throws ArithmeticException if numeric overflow occurs482*/483@Override484public long getLong(TemporalField field) {485if (field instanceof ChronoField) {486switch ((ChronoField) field) {487case MONTH_OF_YEAR: return month;488case PROLEPTIC_MONTH: return getProlepticMonth();489case YEAR_OF_ERA: return (year < 1 ? 1 - year : year);490case YEAR: return year;491case ERA: return (year < 1 ? 0 : 1);492}493throw new UnsupportedTemporalTypeException("Unsupported field: " + field);494}495return field.getFrom(this);496}497498private long getProlepticMonth() {499return (year * 12L + month - 1);500}501502//-----------------------------------------------------------------------503/**504* Gets the year field.505* <p>506* This method returns the primitive {@code int} value for the year.507* <p>508* The year returned by this method is proleptic as per {@code get(YEAR)}.509*510* @return the year, from MIN_YEAR to MAX_YEAR511*/512public int getYear() {513return year;514}515516/**517* Gets the month-of-year field from 1 to 12.518* <p>519* This method returns the month as an {@code int} from 1 to 12.520* Application code is frequently clearer if the enum {@link Month}521* is used by calling {@link #getMonth()}.522*523* @return the month-of-year, from 1 to 12524* @see #getMonth()525*/526public int getMonthValue() {527return month;528}529530/**531* Gets the month-of-year field using the {@code Month} enum.532* <p>533* This method returns the enum {@link Month} for the month.534* This avoids confusion as to what {@code int} values mean.535* If you need access to the primitive {@code int} value then the enum536* provides the {@link Month#getValue() int value}.537*538* @return the month-of-year, not null539* @see #getMonthValue()540*/541public Month getMonth() {542return Month.of(month);543}544545//-----------------------------------------------------------------------546/**547* Checks if the year is a leap year, according to the ISO proleptic548* calendar system rules.549* <p>550* This method applies the current rules for leap years across the whole time-line.551* In general, a year is a leap year if it is divisible by four without552* remainder. However, years divisible by 100, are not leap years, with553* the exception of years divisible by 400 which are.554* <p>555* For example, 1904 is a leap year it is divisible by 4.556* 1900 was not a leap year as it is divisible by 100, however 2000 was a557* leap year as it is divisible by 400.558* <p>559* The calculation is proleptic - applying the same rules into the far future and far past.560* This is historically inaccurate, but is correct for the ISO-8601 standard.561*562* @return true if the year is leap, false otherwise563*/564public boolean isLeapYear() {565return IsoChronology.INSTANCE.isLeapYear(year);566}567568/**569* Checks if the day-of-month is valid for this year-month.570* <p>571* This method checks whether this year and month and the input day form572* a valid date.573*574* @param dayOfMonth the day-of-month to validate, from 1 to 31, invalid value returns false575* @return true if the day is valid for this year-month576*/577public boolean isValidDay(int dayOfMonth) {578return dayOfMonth >= 1 && dayOfMonth <= lengthOfMonth();579}580581/**582* Returns the length of the month, taking account of the year.583* <p>584* This returns the length of the month in days.585* For example, a date in January would return 31.586*587* @return the length of the month in days, from 28 to 31588*/589public int lengthOfMonth() {590return getMonth().length(isLeapYear());591}592593/**594* Returns the length of the year.595* <p>596* This returns the length of the year in days, either 365 or 366.597*598* @return 366 if the year is leap, 365 otherwise599*/600public int lengthOfYear() {601return (isLeapYear() ? 366 : 365);602}603604//-----------------------------------------------------------------------605/**606* Returns an adjusted copy of this year-month.607* <p>608* This returns a {@code YearMonth}, based on this one, with the year-month adjusted.609* The adjustment takes place using the specified adjuster strategy object.610* Read the documentation of the adjuster to understand what adjustment will be made.611* <p>612* A simple adjuster might simply set the one of the fields, such as the year field.613* A more complex adjuster might set the year-month to the next month that614* Halley's comet will pass the Earth.615* <p>616* The result of this method is obtained by invoking the617* {@link TemporalAdjuster#adjustInto(Temporal)} method on the618* specified adjuster passing {@code this} as the argument.619* <p>620* This instance is immutable and unaffected by this method call.621*622* @param adjuster the adjuster to use, not null623* @return a {@code YearMonth} based on {@code this} with the adjustment made, not null624* @throws DateTimeException if the adjustment cannot be made625* @throws ArithmeticException if numeric overflow occurs626*/627@Override628public YearMonth with(TemporalAdjuster adjuster) {629return (YearMonth) adjuster.adjustInto(this);630}631632/**633* Returns a copy of this year-month with the specified field set to a new value.634* <p>635* This returns a {@code YearMonth}, based on this one, with the value636* for the specified field changed.637* This can be used to change any supported field, such as the year or month.638* If it is not possible to set the value, because the field is not supported or for639* some other reason, an exception is thrown.640* <p>641* If the field is a {@link ChronoField} then the adjustment is implemented here.642* The supported fields behave as follows:643* <ul>644* <li>{@code MONTH_OF_YEAR} -645* Returns a {@code YearMonth} with the specified month-of-year.646* The year will be unchanged.647* <li>{@code PROLEPTIC_MONTH} -648* Returns a {@code YearMonth} with the specified proleptic-month.649* This completely replaces the year and month of this object.650* <li>{@code YEAR_OF_ERA} -651* Returns a {@code YearMonth} with the specified year-of-era652* The month and era will be unchanged.653* <li>{@code YEAR} -654* Returns a {@code YearMonth} with the specified year.655* The month will be unchanged.656* <li>{@code ERA} -657* Returns a {@code YearMonth} with the specified era.658* The month and year-of-era will be unchanged.659* </ul>660* <p>661* In all cases, if the new value is outside the valid range of values for the field662* then a {@code DateTimeException} will be thrown.663* <p>664* All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.665* <p>666* If the field is not a {@code ChronoField}, then the result of this method667* is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)}668* passing {@code this} as the argument. In this case, the field determines669* whether and how to adjust the instant.670* <p>671* This instance is immutable and unaffected by this method call.672*673* @param field the field to set in the result, not null674* @param newValue the new value of the field in the result675* @return a {@code YearMonth} based on {@code this} with the specified field set, not null676* @throws DateTimeException if the field cannot be set677* @throws UnsupportedTemporalTypeException if the field is not supported678* @throws ArithmeticException if numeric overflow occurs679*/680@Override681public YearMonth with(TemporalField field, long newValue) {682if (field instanceof ChronoField) {683ChronoField f = (ChronoField) field;684f.checkValidValue(newValue);685switch (f) {686case MONTH_OF_YEAR: return withMonth((int) newValue);687case PROLEPTIC_MONTH: return plusMonths(newValue - getProlepticMonth());688case YEAR_OF_ERA: return withYear((int) (year < 1 ? 1 - newValue : newValue));689case YEAR: return withYear((int) newValue);690case ERA: return (getLong(ERA) == newValue ? this : withYear(1 - year));691}692throw new UnsupportedTemporalTypeException("Unsupported field: " + field);693}694return field.adjustInto(this, newValue);695}696697//-----------------------------------------------------------------------698/**699* Returns a copy of this {@code YearMonth} with the year altered.700* <p>701* This instance is immutable and unaffected by this method call.702*703* @param year the year to set in the returned year-month, from MIN_YEAR to MAX_YEAR704* @return a {@code YearMonth} based on this year-month with the requested year, not null705* @throws DateTimeException if the year value is invalid706*/707public YearMonth withYear(int year) {708YEAR.checkValidValue(year);709return with(year, month);710}711712/**713* Returns a copy of this {@code YearMonth} with the month-of-year altered.714* <p>715* This instance is immutable and unaffected by this method call.716*717* @param month the month-of-year to set in the returned year-month, from 1 (January) to 12 (December)718* @return a {@code YearMonth} based on this year-month with the requested month, not null719* @throws DateTimeException if the month-of-year value is invalid720*/721public YearMonth withMonth(int month) {722MONTH_OF_YEAR.checkValidValue(month);723return with(year, month);724}725726//-----------------------------------------------------------------------727/**728* Returns a copy of this year-month with the specified amount added.729* <p>730* This returns a {@code YearMonth}, based on this one, with the specified amount added.731* The amount is typically {@link Period} but may be any other type implementing732* the {@link TemporalAmount} interface.733* <p>734* The calculation is delegated to the amount object by calling735* {@link TemporalAmount#addTo(Temporal)}. The amount implementation is free736* to implement the addition in any way it wishes, however it typically737* calls back to {@link #plus(long, TemporalUnit)}. Consult the documentation738* of the amount implementation to determine if it can be successfully added.739* <p>740* This instance is immutable and unaffected by this method call.741*742* @param amountToAdd the amount to add, not null743* @return a {@code YearMonth} based on this year-month with the addition made, not null744* @throws DateTimeException if the addition cannot be made745* @throws ArithmeticException if numeric overflow occurs746*/747@Override748public YearMonth plus(TemporalAmount amountToAdd) {749return (YearMonth) amountToAdd.addTo(this);750}751752/**753* Returns a copy of this year-month with the specified amount added.754* <p>755* This returns a {@code YearMonth}, based on this one, with the amount756* in terms of the unit added. If it is not possible to add the amount, because the757* unit is not supported or for some other reason, an exception is thrown.758* <p>759* If the field is a {@link ChronoUnit} then the addition is implemented here.760* The supported fields behave as follows:761* <ul>762* <li>{@code MONTHS} -763* Returns a {@code YearMonth} with the specified number of months added.764* This is equivalent to {@link #plusMonths(long)}.765* <li>{@code YEARS} -766* Returns a {@code YearMonth} with the specified number of years added.767* This is equivalent to {@link #plusYears(long)}.768* <li>{@code DECADES} -769* Returns a {@code YearMonth} with the specified number of decades added.770* This is equivalent to calling {@link #plusYears(long)} with the amount771* multiplied by 10.772* <li>{@code CENTURIES} -773* Returns a {@code YearMonth} with the specified number of centuries added.774* This is equivalent to calling {@link #plusYears(long)} with the amount775* multiplied by 100.776* <li>{@code MILLENNIA} -777* Returns a {@code YearMonth} with the specified number of millennia added.778* This is equivalent to calling {@link #plusYears(long)} with the amount779* multiplied by 1,000.780* <li>{@code ERAS} -781* Returns a {@code YearMonth} with the specified number of eras added.782* Only two eras are supported so the amount must be one, zero or minus one.783* If the amount is non-zero then the year is changed such that the year-of-era784* is unchanged.785* </ul>786* <p>787* All other {@code ChronoUnit} instances will throw an {@code UnsupportedTemporalTypeException}.788* <p>789* If the field is not a {@code ChronoUnit}, then the result of this method790* is obtained by invoking {@code TemporalUnit.addTo(Temporal, long)}791* passing {@code this} as the argument. In this case, the unit determines792* whether and how to perform the addition.793* <p>794* This instance is immutable and unaffected by this method call.795*796* @param amountToAdd the amount of the unit to add to the result, may be negative797* @param unit the unit of the amount to add, not null798* @return a {@code YearMonth} based on this year-month with the specified amount added, not null799* @throws DateTimeException if the addition cannot be made800* @throws UnsupportedTemporalTypeException if the unit is not supported801* @throws ArithmeticException if numeric overflow occurs802*/803@Override804public YearMonth plus(long amountToAdd, TemporalUnit unit) {805if (unit instanceof ChronoUnit) {806switch ((ChronoUnit) unit) {807case MONTHS: return plusMonths(amountToAdd);808case YEARS: return plusYears(amountToAdd);809case DECADES: return plusYears(Math.multiplyExact(amountToAdd, 10));810case CENTURIES: return plusYears(Math.multiplyExact(amountToAdd, 100));811case MILLENNIA: return plusYears(Math.multiplyExact(amountToAdd, 1000));812case ERAS: return with(ERA, Math.addExact(getLong(ERA), amountToAdd));813}814throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);815}816return unit.addTo(this, amountToAdd);817}818819/**820* Returns a copy of this {@code YearMonth} with the specified number of years added.821* <p>822* This instance is immutable and unaffected by this method call.823*824* @param yearsToAdd the years to add, may be negative825* @return a {@code YearMonth} based on this year-month with the years added, not null826* @throws DateTimeException if the result exceeds the supported range827*/828public YearMonth plusYears(long yearsToAdd) {829if (yearsToAdd == 0) {830return this;831}832int newYear = YEAR.checkValidIntValue(year + yearsToAdd); // safe overflow833return with(newYear, month);834}835836/**837* Returns a copy of this {@code YearMonth} with the specified number of months added.838* <p>839* This instance is immutable and unaffected by this method call.840*841* @param monthsToAdd the months to add, may be negative842* @return a {@code YearMonth} based on this year-month with the months added, not null843* @throws DateTimeException if the result exceeds the supported range844*/845public YearMonth plusMonths(long monthsToAdd) {846if (monthsToAdd == 0) {847return this;848}849long monthCount = year * 12L + (month - 1);850long calcMonths = monthCount + monthsToAdd; // safe overflow851int newYear = YEAR.checkValidIntValue(Math.floorDiv(calcMonths, 12));852int newMonth = (int)Math.floorMod(calcMonths, 12) + 1;853return with(newYear, newMonth);854}855856//-----------------------------------------------------------------------857/**858* Returns a copy of this year-month with the specified amount subtracted.859* <p>860* This returns a {@code YearMonth}, based on this one, with the specified amount subtracted.861* The amount is typically {@link Period} but may be any other type implementing862* the {@link TemporalAmount} interface.863* <p>864* The calculation is delegated to the amount object by calling865* {@link TemporalAmount#subtractFrom(Temporal)}. The amount implementation is free866* to implement the subtraction in any way it wishes, however it typically867* calls back to {@link #minus(long, TemporalUnit)}. Consult the documentation868* of the amount implementation to determine if it can be successfully subtracted.869* <p>870* This instance is immutable and unaffected by this method call.871*872* @param amountToSubtract the amount to subtract, not null873* @return a {@code YearMonth} based on this year-month with the subtraction made, not null874* @throws DateTimeException if the subtraction cannot be made875* @throws ArithmeticException if numeric overflow occurs876*/877@Override878public YearMonth minus(TemporalAmount amountToSubtract) {879return (YearMonth) amountToSubtract.subtractFrom(this);880}881882/**883* Returns a copy of this year-month with the specified amount subtracted.884* <p>885* This returns a {@code YearMonth}, based on this one, with the amount886* in terms of the unit subtracted. If it is not possible to subtract the amount,887* because the unit is not supported or for some other reason, an exception is thrown.888* <p>889* This method is equivalent to {@link #plus(long, TemporalUnit)} with the amount negated.890* See that method for a full description of how addition, and thus subtraction, works.891* <p>892* This instance is immutable and unaffected by this method call.893*894* @param amountToSubtract the amount of the unit to subtract from the result, may be negative895* @param unit the unit of the amount to subtract, not null896* @return a {@code YearMonth} based on this year-month with the specified amount subtracted, not null897* @throws DateTimeException if the subtraction cannot be made898* @throws UnsupportedTemporalTypeException if the unit is not supported899* @throws ArithmeticException if numeric overflow occurs900*/901@Override902public YearMonth minus(long amountToSubtract, TemporalUnit unit) {903return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit));904}905906/**907* Returns a copy of this {@code YearMonth} with the specified number of years subtracted.908* <p>909* This instance is immutable and unaffected by this method call.910*911* @param yearsToSubtract the years to subtract, may be negative912* @return a {@code YearMonth} based on this year-month with the years subtracted, not null913* @throws DateTimeException if the result exceeds the supported range914*/915public YearMonth minusYears(long yearsToSubtract) {916return (yearsToSubtract == Long.MIN_VALUE ? plusYears(Long.MAX_VALUE).plusYears(1) : plusYears(-yearsToSubtract));917}918919/**920* Returns a copy of this {@code YearMonth} with the specified number of months subtracted.921* <p>922* This instance is immutable and unaffected by this method call.923*924* @param monthsToSubtract the months to subtract, may be negative925* @return a {@code YearMonth} based on this year-month with the months subtracted, not null926* @throws DateTimeException if the result exceeds the supported range927*/928public YearMonth minusMonths(long monthsToSubtract) {929return (monthsToSubtract == Long.MIN_VALUE ? plusMonths(Long.MAX_VALUE).plusMonths(1) : plusMonths(-monthsToSubtract));930}931932//-----------------------------------------------------------------------933/**934* Queries this year-month using the specified query.935* <p>936* This queries this year-month using the specified query strategy object.937* The {@code TemporalQuery} object defines the logic to be used to938* obtain the result. Read the documentation of the query to understand939* what the result of this method will be.940* <p>941* The result of this method is obtained by invoking the942* {@link TemporalQuery#queryFrom(TemporalAccessor)} method on the943* specified query passing {@code this} as the argument.944*945* @param <R> the type of the result946* @param query the query to invoke, not null947* @return the query result, null may be returned (defined by the query)948* @throws DateTimeException if unable to query (defined by the query)949* @throws ArithmeticException if numeric overflow occurs (defined by the query)950*/951@SuppressWarnings("unchecked")952@Override953public <R> R query(TemporalQuery<R> query) {954if (query == TemporalQueries.chronology()) {955return (R) IsoChronology.INSTANCE;956} else if (query == TemporalQueries.precision()) {957return (R) MONTHS;958}959return Temporal.super.query(query);960}961962/**963* Adjusts the specified temporal object to have this year-month.964* <p>965* This returns a temporal object of the same observable type as the input966* with the year and month changed to be the same as this.967* <p>968* The adjustment is equivalent to using {@link Temporal#with(TemporalField, long)}969* passing {@link ChronoField#PROLEPTIC_MONTH} as the field.970* If the specified temporal object does not use the ISO calendar system then971* a {@code DateTimeException} is thrown.972* <p>973* In most cases, it is clearer to reverse the calling pattern by using974* {@link Temporal#with(TemporalAdjuster)}:975* <pre>976* // these two lines are equivalent, but the second approach is recommended977* temporal = thisYearMonth.adjustInto(temporal);978* temporal = temporal.with(thisYearMonth);979* </pre>980* <p>981* This instance is immutable and unaffected by this method call.982*983* @param temporal the target object to be adjusted, not null984* @return the adjusted object, not null985* @throws DateTimeException if unable to make the adjustment986* @throws ArithmeticException if numeric overflow occurs987*/988@Override989public Temporal adjustInto(Temporal temporal) {990if (Chronology.from(temporal).equals(IsoChronology.INSTANCE) == false) {991throw new DateTimeException("Adjustment only supported on ISO date-time");992}993return temporal.with(PROLEPTIC_MONTH, getProlepticMonth());994}995996/**997* Calculates the amount of time until another year-month in terms of the specified unit.998* <p>999* This calculates the amount of time between two {@code YearMonth}1000* objects in terms of a single {@code TemporalUnit}.1001* The start and end points are {@code this} and the specified year-month.1002* The result will be negative if the end is before the start.1003* The {@code Temporal} passed to this method is converted to a1004* {@code YearMonth} using {@link #from(TemporalAccessor)}.1005* For example, the amount in years between two year-months can be calculated1006* using {@code startYearMonth.until(endYearMonth, YEARS)}.1007* <p>1008* The calculation returns a whole number, representing the number of1009* complete units between the two year-months.1010* For example, the amount in decades between 2012-06 and 2032-051011* will only be one decade as it is one month short of two decades.1012* <p>1013* There are two equivalent ways of using this method.1014* The first is to invoke this method.1015* The second is to use {@link TemporalUnit#between(Temporal, Temporal)}:1016* <pre>1017* // these two lines are equivalent1018* amount = start.until(end, MONTHS);1019* amount = MONTHS.between(start, end);1020* </pre>1021* The choice should be made based on which makes the code more readable.1022* <p>1023* The calculation is implemented in this method for {@link ChronoUnit}.1024* The units {@code MONTHS}, {@code YEARS}, {@code DECADES},1025* {@code CENTURIES}, {@code MILLENNIA} and {@code ERAS} are supported.1026* Other {@code ChronoUnit} values will throw an exception.1027* <p>1028* If the unit is not a {@code ChronoUnit}, then the result of this method1029* is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)}1030* passing {@code this} as the first argument and the converted input temporal1031* as the second argument.1032* <p>1033* This instance is immutable and unaffected by this method call.1034*1035* @param endExclusive the end date, exclusive, which is converted to a {@code YearMonth}, not null1036* @param unit the unit to measure the amount in, not null1037* @return the amount of time between this year-month and the end year-month1038* @throws DateTimeException if the amount cannot be calculated, or the end1039* temporal cannot be converted to a {@code YearMonth}1040* @throws UnsupportedTemporalTypeException if the unit is not supported1041* @throws ArithmeticException if numeric overflow occurs1042*/1043@Override1044public long until(Temporal endExclusive, TemporalUnit unit) {1045YearMonth end = YearMonth.from(endExclusive);1046if (unit instanceof ChronoUnit) {1047long monthsUntil = end.getProlepticMonth() - getProlepticMonth(); // no overflow1048switch ((ChronoUnit) unit) {1049case MONTHS: return monthsUntil;1050case YEARS: return monthsUntil / 12;1051case DECADES: return monthsUntil / 120;1052case CENTURIES: return monthsUntil / 1200;1053case MILLENNIA: return monthsUntil / 12000;1054case ERAS: return end.getLong(ERA) - getLong(ERA);1055}1056throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);1057}1058return unit.between(this, end);1059}10601061/**1062* Formats this year-month using the specified formatter.1063* <p>1064* This year-month will be passed to the formatter to produce a string.1065*1066* @param formatter the formatter to use, not null1067* @return the formatted year-month string, not null1068* @throws DateTimeException if an error occurs during printing1069*/1070public String format(DateTimeFormatter formatter) {1071Objects.requireNonNull(formatter, "formatter");1072return formatter.format(this);1073}10741075//-----------------------------------------------------------------------1076/**1077* Combines this year-month with a day-of-month to create a {@code LocalDate}.1078* <p>1079* This returns a {@code LocalDate} formed from this year-month and the specified day-of-month.1080* <p>1081* The day-of-month value must be valid for the year-month.1082* <p>1083* This method can be used as part of a chain to produce a date:1084* <pre>1085* LocalDate date = year.atMonth(month).atDay(day);1086* </pre>1087*1088* @param dayOfMonth the day-of-month to use, from 1 to 311089* @return the date formed from this year-month and the specified day, not null1090* @throws DateTimeException if the day is invalid for the year-month1091* @see #isValidDay(int)1092*/1093public LocalDate atDay(int dayOfMonth) {1094return LocalDate.of(year, month, dayOfMonth);1095}10961097/**1098* Returns a {@code LocalDate} at the end of the month.1099* <p>1100* This returns a {@code LocalDate} based on this year-month.1101* The day-of-month is set to the last valid day of the month, taking1102* into account leap years.1103* <p>1104* This method can be used as part of a chain to produce a date:1105* <pre>1106* LocalDate date = year.atMonth(month).atEndOfMonth();1107* </pre>1108*1109* @return the last valid date of this year-month, not null1110*/1111public LocalDate atEndOfMonth() {1112return LocalDate.of(year, month, lengthOfMonth());1113}11141115//-----------------------------------------------------------------------1116/**1117* Compares this year-month to another year-month.1118* <p>1119* The comparison is based first on the value of the year, then on the value of the month.1120* It is "consistent with equals", as defined by {@link Comparable}.1121*1122* @param other the other year-month to compare to, not null1123* @return the comparator value, negative if less, positive if greater1124*/1125@Override1126public int compareTo(YearMonth other) {1127int cmp = (year - other.year);1128if (cmp == 0) {1129cmp = (month - other.month);1130}1131return cmp;1132}11331134/**1135* Checks if this year-month is after the specified year-month.1136*1137* @param other the other year-month to compare to, not null1138* @return true if this is after the specified year-month1139*/1140public boolean isAfter(YearMonth other) {1141return compareTo(other) > 0;1142}11431144/**1145* Checks if this year-month is before the specified year-month.1146*1147* @param other the other year-month to compare to, not null1148* @return true if this point is before the specified year-month1149*/1150public boolean isBefore(YearMonth other) {1151return compareTo(other) < 0;1152}11531154//-----------------------------------------------------------------------1155/**1156* Checks if this year-month is equal to another year-month.1157* <p>1158* The comparison is based on the time-line position of the year-months.1159*1160* @param obj the object to check, null returns false1161* @return true if this is equal to the other year-month1162*/1163@Override1164public boolean equals(Object obj) {1165if (this == obj) {1166return true;1167}1168if (obj instanceof YearMonth) {1169YearMonth other = (YearMonth) obj;1170return year == other.year && month == other.month;1171}1172return false;1173}11741175/**1176* A hash code for this year-month.1177*1178* @return a suitable hash code1179*/1180@Override1181public int hashCode() {1182return year ^ (month << 27);1183}11841185//-----------------------------------------------------------------------1186/**1187* Outputs this year-month as a {@code String}, such as {@code 2007-12}.1188* <p>1189* The output will be in the format {@code uuuu-MM}:1190*1191* @return a string representation of this year-month, not null1192*/1193@Override1194public String toString() {1195int absYear = Math.abs(year);1196StringBuilder buf = new StringBuilder(9);1197if (absYear < 1000) {1198if (year < 0) {1199buf.append(year - 10000).deleteCharAt(1);1200} else {1201buf.append(year + 10000).deleteCharAt(0);1202}1203} else {1204buf.append(year);1205}1206return buf.append(month < 10 ? "-0" : "-")1207.append(month)1208.toString();1209}12101211//-----------------------------------------------------------------------1212/**1213* Writes the object using a1214* <a href="../../serialized-form.html#java.time.Ser">dedicated serialized form</a>.1215* @serialData1216* <pre>1217* out.writeByte(12); // identifies a YearMonth1218* out.writeInt(year);1219* out.writeByte(month);1220* </pre>1221*1222* @return the instance of {@code Ser}, not null1223*/1224private Object writeReplace() {1225return new Ser(Ser.YEAR_MONTH_TYPE, this);1226}12271228/**1229* Defend against malicious streams.1230*1231* @param s the stream to read1232* @throws InvalidObjectException always1233*/1234private void readObject(ObjectInputStream s) throws InvalidObjectException {1235throw new InvalidObjectException("Deserialization via serialization delegate");1236}12371238void writeExternal(DataOutput out) throws IOException {1239out.writeInt(year);1240out.writeByte(month);1241}12421243static YearMonth readExternal(DataInput in) throws IOException {1244int year = in.readInt();1245byte month = in.readByte();1246return YearMonth.of(year, month);1247}12481249}125012511252