001/*
002 * Copyright (c) 2007-2013, Stephen Colebourne & Michael Nascimento Santos
003 *
004 * All rights reserved.
005 *
006 * Redistribution and use in source and binary forms, with or without
007 * modification, are permitted provided that the following conditions are met:
008 *
009 *  * Redistributions of source code must retain the above copyright notice,
010 *    this list of conditions and the following disclaimer.
011 *
012 *  * Redistributions in binary form must reproduce the above copyright notice,
013 *    this list of conditions and the following disclaimer in the documentation
014 *    and/or other materials provided with the distribution.
015 *
016 *  * Neither the name of JSR-310 nor the names of its contributors
017 *    may be used to endorse or promote products derived from this software
018 *    without specific prior written permission.
019 *
020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
021 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
022 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
023 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
024 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
027 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
028 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
029 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
030 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031 */
032package org.threeten.bp;
033
034import static org.threeten.bp.temporal.ChronoField.EPOCH_MONTH;
035import static org.threeten.bp.temporal.ChronoField.ERA;
036import static org.threeten.bp.temporal.ChronoField.MONTH_OF_YEAR;
037import static org.threeten.bp.temporal.ChronoField.YEAR;
038import static org.threeten.bp.temporal.ChronoField.YEAR_OF_ERA;
039import static org.threeten.bp.temporal.ChronoUnit.MONTHS;
040
041import java.io.DataInput;
042import java.io.DataOutput;
043import java.io.IOException;
044import java.io.InvalidObjectException;
045import java.io.ObjectStreamException;
046import java.io.Serializable;
047import java.util.Objects;
048
049import org.threeten.bp.format.DateTimeFormatter;
050import org.threeten.bp.format.DateTimeFormatterBuilder;
051import org.threeten.bp.format.DateTimeParseException;
052import org.threeten.bp.format.SignStyle;
053import org.threeten.bp.jdk8.DefaultInterfaceTemporalAccessor;
054import org.threeten.bp.jdk8.Jdk8Methods;
055import org.threeten.bp.temporal.Chrono;
056import org.threeten.bp.temporal.ChronoField;
057import org.threeten.bp.temporal.ChronoUnit;
058import org.threeten.bp.temporal.ISOChrono;
059import org.threeten.bp.temporal.Temporal;
060import org.threeten.bp.temporal.TemporalAccessor;
061import org.threeten.bp.temporal.TemporalAdder;
062import org.threeten.bp.temporal.TemporalAdjuster;
063import org.threeten.bp.temporal.TemporalField;
064import org.threeten.bp.temporal.TemporalQueries;
065import org.threeten.bp.temporal.TemporalQuery;
066import org.threeten.bp.temporal.TemporalSubtractor;
067import org.threeten.bp.temporal.TemporalUnit;
068import org.threeten.bp.temporal.ValueRange;
069
070/**
071 * A year-month in the ISO-8601 calendar system, such as {@code 2007-12}.
072 * <p>
073 * {@code YearMonth} is an immutable date-time object that represents the combination
074 * of a year and month. Any field that can be derived from a year and month, such as
075 * quarter-of-year, can be obtained.
076 * <p>
077 * This class does not store or represent a day, time or time-zone.
078 * For example, the value "October 2007" can be stored in a {@code YearMonth}.
079 * <p>
080 * The ISO-8601 calendar system is the modern civil calendar system used today
081 * in most of the world. It is equivalent to the proleptic Gregorian calendar
082 * system, in which todays's rules for leap years are applied for all time.
083 * For most applications written today, the ISO-8601 rules are entirely suitable.
084 * Any application that uses historical dates should consider using {@code HistoricDate}.
085 *
086 * <h3>Specification for implementors</h3>
087 * This class is immutable and thread-safe.
088 */
089public final class YearMonth
090        extends DefaultInterfaceTemporalAccessor
091        implements Temporal, TemporalAdjuster, Comparable<YearMonth>, Serializable {
092
093    /**
094     * Serialization version.
095     */
096    private static final long serialVersionUID = 4183400860270640070L;
097    /**
098     * Parser.
099     */
100    private static final DateTimeFormatter PARSER = new DateTimeFormatterBuilder()
101        .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
102        .appendLiteral('-')
103        .appendValue(MONTH_OF_YEAR, 2)
104        .toFormatter();
105
106    /**
107     * The year.
108     */
109    private final int year;
110    /**
111     * The month-of-year, not null.
112     */
113    private final int month;
114
115    //-----------------------------------------------------------------------
116    /**
117     * Obtains the current year-month from the system clock in the default time-zone.
118     * <p>
119     * This will query the {@link Clock#systemDefaultZone() system clock} in the default
120     * time-zone to obtain the current year-month.
121     * The zone and offset will be set based on the time-zone in the clock.
122     * <p>
123     * Using this method will prevent the ability to use an alternate clock for testing
124     * because the clock is hard-coded.
125     *
126     * @return the current year-month using the system clock and default time-zone, not null
127     */
128    public static YearMonth now() {
129        return now(Clock.systemDefaultZone());
130    }
131
132    /**
133     * Obtains the current year-month from the system clock in the specified time-zone.
134     * <p>
135     * This will query the {@link Clock#system(ZoneId) system clock} to obtain the current year-month.
136     * Specifying the time-zone avoids dependence on the default time-zone.
137     * <p>
138     * Using this method will prevent the ability to use an alternate clock for testing
139     * because the clock is hard-coded.
140     *
141     * @param zone  the zone ID to use, not null
142     * @return the current year-month using the system clock, not null
143     */
144    public static YearMonth now(ZoneId zone) {
145        return now(Clock.system(zone));
146    }
147
148    /**
149     * Obtains the current year-month from the specified clock.
150     * <p>
151     * This will query the specified clock to obtain the current year-month.
152     * Using this method allows the use of an alternate clock for testing.
153     * The alternate clock may be introduced using {@link Clock dependency injection}.
154     *
155     * @param clock  the clock to use, not null
156     * @return the current year-month, not null
157     */
158    public static YearMonth now(Clock clock) {
159        final LocalDate now = LocalDate.now(clock);  // called once
160        return YearMonth.of(now.getYear(), now.getMonth());
161    }
162
163    //-----------------------------------------------------------------------
164    /**
165     * Obtains an instance of {@code YearMonth} from a year and month.
166     *
167     * @param year  the year to represent, from MIN_YEAR to MAX_YEAR
168     * @param month  the month-of-year to represent, not null
169     * @return the year-month, not null
170     * @throws DateTimeException if the year value is invalid
171     */
172    public static YearMonth of(int year, Month month) {
173        Objects.requireNonNull(month, "month");
174        return of(year, month.getValue());
175    }
176
177    /**
178     * Obtains an instance of {@code YearMonth} from a year and month.
179     *
180     * @param year  the year to represent, from MIN_YEAR to MAX_YEAR
181     * @param month  the month-of-year to represent, from 1 (January) to 12 (December)
182     * @return the year-month, not null
183     * @throws DateTimeException if either field value is invalid
184     */
185    public static YearMonth of(int year, int month) {
186        YEAR.checkValidValue(year);
187        MONTH_OF_YEAR.checkValidValue(month);
188        return new YearMonth(year, month);
189    }
190
191    //-----------------------------------------------------------------------
192    /**
193     * Obtains an instance of {@code YearMonth} from a temporal object.
194     * <p>
195     * A {@code TemporalAccessor} represents some form of date and time information.
196     * This factory converts the arbitrary temporal object to an instance of {@code YearMonth}.
197     * <p>
198     * The conversion extracts the {@link ChronoField#YEAR YEAR} and
199     * {@link ChronoField#MONTH_OF_YEAR MONTH_OF_YEAR} fields.
200     * The extraction is only permitted if the temporal object has an ISO
201     * chronology, or can be converted to a {@code LocalDate}.
202     * <p>
203     * This method matches the signature of the functional interface {@link TemporalQuery}
204     * allowing it to be used in queries via method reference, {@code YearMonth::from}.
205     *
206     * @param temporal  the temporal object to convert, not null
207     * @return the year-month, not null
208     * @throws DateTimeException if unable to convert to a {@code YearMonth}
209     */
210    public static YearMonth from(TemporalAccessor temporal) {
211        if (temporal instanceof YearMonth) {
212            return (YearMonth) temporal;
213        }
214        try {
215            if (ISOChrono.INSTANCE.equals(Chrono.from(temporal)) == false) {
216                temporal = LocalDate.from(temporal);
217            }
218            return of(temporal.get(YEAR), temporal.get(MONTH_OF_YEAR));
219        } catch (DateTimeException ex) {
220            throw new DateTimeException("Unable to obtain YearMonth from TemporalAccessor: " + temporal.getClass(), ex);
221        }
222    }
223
224    //-----------------------------------------------------------------------
225    /**
226     * Obtains an instance of {@code YearMonth} from a text string such as {@code 2007-12}.
227     * <p>
228     * The string must represent a valid year-month.
229     * The format must be {@code yyyy-MM}.
230     * Years outside the range 0000 to 9999 must be prefixed by the plus or minus symbol.
231     *
232     * @param text  the text to parse such as "2007-12", not null
233     * @return the parsed year-month, not null
234     * @throws DateTimeParseException if the text cannot be parsed
235     */
236    public static YearMonth parse(CharSequence text) {
237        return parse(text, PARSER);
238    }
239
240    /**
241     * Obtains an instance of {@code YearMonth} from a text string using a specific formatter.
242     * <p>
243     * The text is parsed using the formatter, returning a year-month.
244     *
245     * @param text  the text to parse, not null
246     * @param formatter  the formatter to use, not null
247     * @return the parsed year-month, not null
248     * @throws DateTimeParseException if the text cannot be parsed
249     */
250    public static YearMonth parse(CharSequence text, DateTimeFormatter formatter) {
251        Objects.requireNonNull(formatter, "formatter");
252        return formatter.parse(text, YearMonth.class);
253    }
254
255    //-----------------------------------------------------------------------
256    /**
257     * Constructor.
258     *
259     * @param year  the year to represent, validated from MIN_YEAR to MAX_YEAR
260     * @param month  the month-of-year to represent, validated from 1 (January) to 12 (December)
261     */
262    private YearMonth(int year, int month) {
263        this.year = year;
264        this.month = month;
265    }
266
267    /**
268     * Returns a copy of this year-month with the new year and month, checking
269     * to see if a new object is in fact required.
270     *
271     * @param newYear  the year to represent, validated from MIN_YEAR to MAX_YEAR
272     * @param newMonth  the month-of-year to represent, validated not null
273     * @return the year-month, not null
274     */
275    private YearMonth with(int newYear, int newMonth) {
276        if (year == newYear && month == newMonth) {
277            return this;
278        }
279        return new YearMonth(newYear, newMonth);
280    }
281
282    //-----------------------------------------------------------------------
283    /**
284     * Checks if the specified field is supported.
285     * <p>
286     * This checks if this year-month can be queried for the specified field.
287     * If false, then calling the {@link #range(TemporalField) range} and
288     * {@link #get(TemporalField) get} methods will throw an exception.
289     * <p>
290     * If the field is a {@link ChronoField} then the query is implemented here.
291     * The {@link #isSupported(TemporalField) supported fields} will return valid
292     * values based on this date-time.
293     * The supported fields are:
294     * <ul>
295     * <li>{@code MONTH_OF_YEAR}
296     * <li>{@code EPOCH_MONTH}
297     * <li>{@code YEAR_OF_ERA}
298     * <li>{@code YEAR}
299     * <li>{@code ERA}
300     * </ul>
301     * All other {@code ChronoField} instances will return false.
302     * <p>
303     * If the field is not a {@code ChronoField}, then the result of this method
304     * is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)}
305     * passing {@code this} as the argument.
306     * Whether the field is supported is determined by the field.
307     *
308     * @param field  the field to check, null returns false
309     * @return true if the field is supported on this year-month, false if not
310     */
311    @Override
312    public boolean isSupported(TemporalField field) {
313        if (field instanceof ChronoField) {
314            return field == YEAR || field == MONTH_OF_YEAR ||
315                    field == EPOCH_MONTH || field == YEAR_OF_ERA || field == ERA;
316        }
317        return field != null && field.doIsSupported(this);
318    }
319
320    /**
321     * Gets the range of valid values for the specified field.
322     * <p>
323     * The range object expresses the minimum and maximum valid values for a field.
324     * This year-month is used to enhance the accuracy of the returned range.
325     * If it is not possible to return the range, because the field is not supported
326     * or for some other reason, an exception is thrown.
327     * <p>
328     * If the field is a {@link ChronoField} then the query is implemented here.
329     * The {@link #isSupported(TemporalField) supported fields} will return
330     * appropriate range instances.
331     * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
332     * <p>
333     * If the field is not a {@code ChronoField}, then the result of this method
334     * is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)}
335     * passing {@code this} as the argument.
336     * Whether the range can be obtained is determined by the field.
337     *
338     * @param field  the field to query the range for, not null
339     * @return the range of valid values for the field, not null
340     * @throws DateTimeException if the range for the field cannot be obtained
341     */
342    @Override
343    public ValueRange range(TemporalField field) {
344        if (field == YEAR_OF_ERA) {
345            return (getYear() <= 0 ? ValueRange.of(1, Year.MAX_VALUE + 1) : ValueRange.of(1, Year.MAX_VALUE));
346        }
347        return super.range(field);
348    }
349
350    /**
351     * Gets the value of the specified field from this year-month as an {@code int}.
352     * <p>
353     * This queries this year-month for the value for the specified field.
354     * The returned value will always be within the valid range of values for the field.
355     * If it is not possible to return the value, because the field is not supported
356     * or for some other reason, an exception is thrown.
357     * <p>
358     * If the field is a {@link ChronoField} then the query is implemented here.
359     * The {@link #isSupported(TemporalField) supported fields} will return valid
360     * values based on this year-month, except {@code EPOCH_MONTH} which is too
361     * large to fit in an {@code int} and throw a {@code DateTimeException}.
362     * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
363     * <p>
364     * If the field is not a {@code ChronoField}, then the result of this method
365     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
366     * passing {@code this} as the argument. Whether the value can be obtained,
367     * and what the value represents, is determined by the field.
368     *
369     * @param field  the field to get, not null
370     * @return the value for the field
371     * @throws DateTimeException if a value for the field cannot be obtained
372     * @throws ArithmeticException if numeric overflow occurs
373     */
374    @Override  // override for Javadoc
375    public int get(TemporalField field) {
376        return range(field).checkValidIntValue(getLong(field), field);
377    }
378
379    /**
380     * Gets the value of the specified field from this year-month as a {@code long}.
381     * <p>
382     * This queries this year-month for the value for the specified field.
383     * If it is not possible to return the value, because the field is not supported
384     * or for some other reason, an exception is thrown.
385     * <p>
386     * If the field is a {@link ChronoField} then the query is implemented here.
387     * The {@link #isSupported(TemporalField) supported fields} will return valid
388     * values based on this year-month.
389     * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
390     * <p>
391     * If the field is not a {@code ChronoField}, then the result of this method
392     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
393     * passing {@code this} as the argument. Whether the value can be obtained,
394     * and what the value represents, is determined by the field.
395     *
396     * @param field  the field to get, not null
397     * @return the value for the field
398     * @throws DateTimeException if a value for the field cannot be obtained
399     * @throws ArithmeticException if numeric overflow occurs
400     */
401    @Override
402    public long getLong(TemporalField field) {
403        if (field instanceof ChronoField) {
404            switch ((ChronoField) field) {
405                case MONTH_OF_YEAR: return month;
406                case EPOCH_MONTH: return getEpochMonth();
407                case YEAR_OF_ERA: return (year < 1 ? 1 - year : year);
408                case YEAR: return year;
409                case ERA: return (year < 1 ? 0 : 1);
410            }
411            throw new DateTimeException("Unsupported field: " + field.getName());
412        }
413        return field.doGet(this);
414    }
415
416    private long getEpochMonth() {
417        return ((year - 1970) * 12L) + (month - 1);
418    }
419
420    //-----------------------------------------------------------------------
421    /**
422     * Gets the year field.
423     * <p>
424     * This method returns the primitive {@code int} value for the year.
425     * <p>
426     * The year returned by this method is proleptic as per {@code get(YEAR)}.
427     *
428     * @return the year, from MIN_YEAR to MAX_YEAR
429     */
430    public int getYear() {
431        return year;
432    }
433
434    /**
435     * Gets the month-of-year field using the {@code Month} enum.
436     * <p>
437     * This method returns the enum {@link Month} for the month.
438     * This avoids confusion as to what {@code int} values mean.
439     * If you need access to the primitive {@code int} value then the enum
440     * provides the {@link Month#getValue() int value}.
441     *
442     * @return the month-of-year, not null
443     */
444    public Month getMonth() {
445        return Month.of(month);
446    }
447
448    //-----------------------------------------------------------------------
449    /**
450     * Checks if the year is a leap year, according to the ISO proleptic
451     * calendar system rules.
452     * <p>
453     * This method applies the current rules for leap years across the whole time-line.
454     * In general, a year is a leap year if it is divisible by four without
455     * remainder. However, years divisible by 100, are not leap years, with
456     * the exception of years divisible by 400 which are.
457     * <p>
458     * For example, 1904 is a leap year it is divisible by 4.
459     * 1900 was not a leap year as it is divisible by 100, however 2000 was a
460     * leap year as it is divisible by 400.
461     * <p>
462     * The calculation is proleptic - applying the same rules into the far future and far past.
463     * This is historically inaccurate, but is correct for the ISO-8601 standard.
464     *
465     * @return true if the year is leap, false otherwise
466     */
467    public boolean isLeapYear() {
468        return ISOChrono.INSTANCE.isLeapYear(year);
469    }
470
471    /**
472     * Checks if the day-of-month is valid for this year-month.
473     * <p>
474     * This method checks whether this year and month and the input day form
475     * a valid date.
476     *
477     * @param dayOfMonth  the day-of-month to validate, from 1 to 31, invalid value returns false
478     * @return true if the day is valid for this year-month
479     */
480    public boolean isValidDay(int dayOfMonth) {
481        return dayOfMonth >= 1 && dayOfMonth <= lengthOfMonth();
482    }
483
484    /**
485     * Returns the length of the month, taking account of the year.
486     * <p>
487     * This returns the length of the month in days.
488     * For example, a date in January would return 31.
489     *
490     * @return the length of the month in days, from 28 to 31
491     */
492    public int lengthOfMonth() {
493        return getMonth().length(isLeapYear());
494    }
495
496    /**
497     * Returns the length of the year.
498     * <p>
499     * This returns the length of the year in days, either 365 or 366.
500     *
501     * @return 366 if the year is leap, 365 otherwise
502     */
503    public int lengthOfYear() {
504        return (isLeapYear() ? 366 : 365);
505    }
506
507    //-----------------------------------------------------------------------
508    /**
509     * Returns an adjusted copy of this year-month.
510     * <p>
511     * This returns a new {@code YearMonth}, based on this one, with the year-month adjusted.
512     * The adjustment takes place using the specified adjuster strategy object.
513     * Read the documentation of the adjuster to understand what adjustment will be made.
514     * <p>
515     * A simple adjuster might simply set the one of the fields, such as the year field.
516     * A more complex adjuster might set the year-month to the next month that
517     * Halley's comet will pass the Earth.
518     * <p>
519     * The result of this method is obtained by invoking the
520     * {@link TemporalAdjuster#adjustInto(Temporal)} method on the
521     * specified adjuster passing {@code this} as the argument.
522     * <p>
523     * This instance is immutable and unaffected by this method call.
524     *
525     * @param adjuster the adjuster to use, not null
526     * @return a {@code YearMonth} based on {@code this} with the adjustment made, not null
527     * @throws DateTimeException if the adjustment cannot be made
528     * @throws ArithmeticException if numeric overflow occurs
529     */
530    @Override
531    public YearMonth with(TemporalAdjuster adjuster) {
532        return (YearMonth) adjuster.adjustInto(this);
533    }
534
535    /**
536     * Returns a copy of this year-month with the specified field set to a new value.
537     * <p>
538     * This returns a new {@code YearMonth}, based on this one, with the value
539     * for the specified field changed.
540     * This can be used to change any supported field, such as the year or month.
541     * If it is not possible to set the value, because the field is not supported or for
542     * some other reason, an exception is thrown.
543     * <p>
544     * If the field is a {@link ChronoField} then the adjustment is implemented here.
545     * The supported fields behave as follows:
546     * <ul>
547     * <li>{@code MONTH_OF_YEAR} -
548     *  Returns a {@code YearMonth} with the specified month-of-year.
549     *  The year will be unchanged.
550     * <li>{@code EPOCH_MONTH} -
551     *  Returns a {@code YearMonth} with the specified epoch-month.
552     *  This completely replaces the year and month of this object.
553     * <li>{@code YEAR_OF_ERA} -
554     *  Returns a {@code YearMonth} with the specified year-of-era
555     *  The month and era will be unchanged.
556     * <li>{@code YEAR} -
557     *  Returns a {@code YearMonth} with the specified year.
558     *  The month will be unchanged.
559     * <li>{@code ERA} -
560     *  Returns a {@code YearMonth} with the specified era.
561     *  The month and year-of-era will be unchanged.
562     * </ul>
563     * <p>
564     * In all cases, if the new value is outside the valid range of values for the field
565     * then a {@code DateTimeException} will be thrown.
566     * <p>
567     * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
568     * <p>
569     * If the field is not a {@code ChronoField}, then the result of this method
570     * is obtained by invoking {@code TemporalField.doWith(Temporal, long)}
571     * passing {@code this} as the argument. In this case, the field determines
572     * whether and how to adjust the instant.
573     * <p>
574     * This instance is immutable and unaffected by this method call.
575     *
576     * @param field  the field to set in the result, not null
577     * @param newValue  the new value of the field in the result
578     * @return a {@code YearMonth} based on {@code this} with the specified field set, not null
579     * @throws DateTimeException if the field cannot be set
580     * @throws ArithmeticException if numeric overflow occurs
581     */
582    @Override
583    public YearMonth with(TemporalField field, long newValue) {
584        if (field instanceof ChronoField) {
585            ChronoField f = (ChronoField) field;
586            f.checkValidValue(newValue);
587            switch (f) {
588                case MONTH_OF_YEAR: return withMonth((int) newValue);
589                case EPOCH_MONTH: return plusMonths(newValue - getLong(EPOCH_MONTH));
590                case YEAR_OF_ERA: return withYear((int) (year < 1 ? 1 - newValue : newValue));
591                case YEAR: return withYear((int) newValue);
592                case ERA: return (getLong(ERA) == newValue ? this : withYear(1 - year));
593            }
594            throw new DateTimeException("Unsupported field: " + field.getName());
595        }
596        return field.doWith(this, newValue);
597    }
598
599    //-----------------------------------------------------------------------
600    /**
601     * Returns a copy of this {@code YearMonth} with the year altered.
602     * <p>
603     * This instance is immutable and unaffected by this method call.
604     *
605     * @param year  the year to set in the returned year-month, from MIN_YEAR to MAX_YEAR
606     * @return a {@code YearMonth} based on this year-month with the requested year, not null
607     * @throws DateTimeException if the year value is invalid
608     */
609    public YearMonth withYear(int year) {
610        YEAR.checkValidValue(year);
611        return with(year, month);
612    }
613
614    /**
615     * Returns a copy of this {@code YearMonth} with the month-of-year altered.
616     * <p>
617     * This instance is immutable and unaffected by this method call.
618     *
619     * @param month  the month-of-year to set in the returned year-month, from 1 (January) to 12 (December)
620     * @return a {@code YearMonth} based on this year-month with the requested month, not null
621     * @throws DateTimeException if the month-of-year value is invalid
622     */
623    public YearMonth withMonth(int month) {
624        MONTH_OF_YEAR.checkValidValue(month);
625        return with(year, month);
626    }
627
628    //-----------------------------------------------------------------------
629    /**
630     * Returns a copy of this year-month with the specified period added.
631     * <p>
632     * This method returns a new year-month based on this year-month with the specified period added.
633     * The adder is typically {@link org.threeten.bp.Period Period} but may be any other type implementing
634     * the {@link TemporalAdder} interface.
635     * The calculation is delegated to the specified adjuster, which typically calls
636     * back to {@link #plus(long, TemporalUnit)}.
637     * <p>
638     * This instance is immutable and unaffected by this method call.
639     *
640     * @param adder  the adder to use, not null
641     * @return a {@code YearMonth} based on this year-month with the addition made, not null
642     * @throws DateTimeException if the addition cannot be made
643     * @throws ArithmeticException if numeric overflow occurs
644     */
645    @Override
646    public YearMonth plus(TemporalAdder adder) {
647        return (YearMonth) adder.addTo(this);
648    }
649
650    /**
651     * {@inheritDoc}
652     * @throws DateTimeException {@inheritDoc}
653     * @throws ArithmeticException {@inheritDoc}
654     */
655    @Override
656    public YearMonth plus(long amountToAdd, TemporalUnit unit) {
657        if (unit instanceof ChronoUnit) {
658            switch ((ChronoUnit) unit) {
659                case MONTHS: return plusMonths(amountToAdd);
660                case YEARS: return plusYears(amountToAdd);
661                case DECADES: return plusYears(Jdk8Methods.safeMultiply(amountToAdd, 10));
662                case CENTURIES: return plusYears(Jdk8Methods.safeMultiply(amountToAdd, 100));
663                case MILLENNIA: return plusYears(Jdk8Methods.safeMultiply(amountToAdd, 1000));
664                case ERAS: return with(ERA, Jdk8Methods.safeAdd(getLong(ERA), amountToAdd));
665            }
666            throw new DateTimeException("Unsupported unit: " + unit.getName());
667        }
668        return unit.doPlus(this, amountToAdd);
669    }
670
671    /**
672     * Returns a copy of this year-month with the specified period in years added.
673     * <p>
674     * This instance is immutable and unaffected by this method call.
675     *
676     * @param yearsToAdd  the years to add, may be negative
677     * @return a {@code YearMonth} based on this year-month with the years added, not null
678     * @throws DateTimeException if the result exceeds the supported range
679     */
680    public YearMonth plusYears(long yearsToAdd) {
681        if (yearsToAdd == 0) {
682            return this;
683        }
684        int newYear = YEAR.checkValidIntValue(year + yearsToAdd);  // safe overflow
685        return with(newYear, month);
686    }
687
688    /**
689     * Returns a copy of this year-month with the specified period in months added.
690     * <p>
691     * This instance is immutable and unaffected by this method call.
692     *
693     * @param monthsToAdd  the months to add, may be negative
694     * @return a {@code YearMonth} based on this year-month with the months added, not null
695     * @throws DateTimeException if the result exceeds the supported range
696     */
697    public YearMonth plusMonths(long monthsToAdd) {
698        if (monthsToAdd == 0) {
699            return this;
700        }
701        long monthCount = year * 12L + (month - 1);
702        long calcMonths = monthCount + monthsToAdd;  // safe overflow
703        int newYear = YEAR.checkValidIntValue(Jdk8Methods.floorDiv(calcMonths, 12));
704        int newMonth = Jdk8Methods.floorMod(calcMonths, 12) + 1;
705        return with(newYear, newMonth);
706    }
707
708    //-----------------------------------------------------------------------
709    /**
710     * Returns a copy of this year-month with the specified period subtracted.
711     * <p>
712     * This method returns a new year-month based on this year-month with the specified period subtracted.
713     * The subtractor is typically {@link org.threeten.bp.Period Period} but may be any other type implementing
714     * the {@link TemporalSubtractor} interface.
715     * The calculation is delegated to the specified adjuster, which typically calls
716     * back to {@link #minus(long, TemporalUnit)}.
717     * <p>
718     * This instance is immutable and unaffected by this method call.
719     *
720     * @param subtractor  the subtractor to use, not null
721     * @return a {@code YearMonth} based on this year-month with the subtraction made, not null
722     * @throws DateTimeException if the subtraction cannot be made
723     * @throws ArithmeticException if numeric overflow occurs
724     */
725    @Override
726    public YearMonth minus(TemporalSubtractor subtractor) {
727        return (YearMonth) subtractor.subtractFrom(this);
728    }
729
730    /**
731     * {@inheritDoc}
732     * @throws DateTimeException {@inheritDoc}
733     * @throws ArithmeticException {@inheritDoc}
734     */
735    @Override
736    public YearMonth minus(long amountToSubtract, TemporalUnit unit) {
737        return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit));
738    }
739
740    /**
741     * Returns a copy of this year-month with the specified period in years subtracted.
742     * <p>
743     * This instance is immutable and unaffected by this method call.
744     *
745     * @param yearsToSubtract  the years to subtract, may be negative
746     * @return a {@code YearMonth} based on this year-month with the years subtracted, not null
747     * @throws DateTimeException if the result exceeds the supported range
748     */
749    public YearMonth minusYears(long yearsToSubtract) {
750        return (yearsToSubtract == Long.MIN_VALUE ? plusYears(Long.MAX_VALUE).plusYears(1) : plusYears(-yearsToSubtract));
751    }
752
753    /**
754     * Returns a copy of this year-month with the specified period in months subtracted.
755     * <p>
756     * This instance is immutable and unaffected by this method call.
757     *
758     * @param monthsToSubtract  the months to subtract, may be negative
759     * @return a {@code YearMonth} based on this year-month with the months subtracted, not null
760     * @throws DateTimeException if the result exceeds the supported range
761     */
762    public YearMonth minusMonths(long monthsToSubtract) {
763        return (monthsToSubtract == Long.MIN_VALUE ? plusMonths(Long.MAX_VALUE).plusMonths(1) : plusMonths(-monthsToSubtract));
764    }
765
766    //-----------------------------------------------------------------------
767    /**
768     * Queries this year-month using the specified query.
769     * <p>
770     * This queries this year-month using the specified query strategy object.
771     * The {@code TemporalQuery} object defines the logic to be used to
772     * obtain the result. Read the documentation of the query to understand
773     * what the result of this method will be.
774     * <p>
775     * The result of this method is obtained by invoking the
776     * {@link TemporalQuery#queryFrom(TemporalAccessor)} method on the
777     * specified query passing {@code this} as the argument.
778     *
779     * @param <R> the type of the result
780     * @param query  the query to invoke, not null
781     * @return the query result, null may be returned (defined by the query)
782     * @throws DateTimeException if unable to query (defined by the query)
783     * @throws ArithmeticException if numeric overflow occurs (defined by the query)
784     */
785    @SuppressWarnings("unchecked")
786    @Override
787    public <R> R query(TemporalQuery<R> query) {
788        if (query == TemporalQueries.chrono()) {
789            return (R) ISOChrono.INSTANCE;
790        } else if (query == TemporalQueries.precision()) {
791            return (R) MONTHS;
792        }
793        return super.query(query);
794    }
795
796    /**
797     * Adjusts the specified temporal object to have this year-month.
798     * <p>
799     * This returns a temporal object of the same observable type as the input
800     * with the year and month changed to be the same as this.
801     * <p>
802     * The adjustment is equivalent to using {@link Temporal#with(TemporalField, long)}
803     * passing {@link ChronoField#EPOCH_MONTH} as the field.
804     * If the specified temporal object does not use the ISO calendar system then
805     * a {@code DateTimeException} is thrown.
806     * <p>
807     * In most cases, it is clearer to reverse the calling pattern by using
808     * {@link Temporal#with(TemporalAdjuster)}:
809     * <pre>
810     *   // these two lines are equivalent, but the second approach is recommended
811     *   temporal = thisYearMonth.adjustInto(temporal);
812     *   temporal = temporal.with(thisYearMonth);
813     * </pre>
814     * <p>
815     * This instance is immutable and unaffected by this method call.
816     *
817     * @param temporal  the target object to be adjusted, not null
818     * @return the adjusted object, not null
819     * @throws DateTimeException if unable to make the adjustment
820     * @throws ArithmeticException if numeric overflow occurs
821     */
822    @Override
823    public Temporal adjustInto(Temporal temporal) {
824        if (Chrono.from(temporal).equals(ISOChrono.INSTANCE) == false) {
825            throw new DateTimeException("Adjustment only supported on ISO date-time");
826        }
827        return temporal.with(EPOCH_MONTH, getEpochMonth());
828    }
829
830    /**
831     * Calculates the period between this year-month and another year-month in
832     * terms of the specified unit.
833     * <p>
834     * This calculates the period between two year-months in terms of a single unit.
835     * The start and end points are {@code this} and the specified year-month.
836     * The result will be negative if the end is before the start.
837     * The {@code Temporal} passed to this method must be a {@code YearMonth}.
838     * For example, the period in years between two year-months can be calculated
839     * using {@code startYearMonth.periodUntil(endYearMonth, YEARS)}.
840     * <p>
841     * The calculation returns a whole number, representing the number of
842     * complete units between the two year-months.
843     * For example, the period in decades between 2012-06 and 2032-05
844     * will only be one decade as it is one month short of two decades.
845     * <p>
846     * This method operates in association with {@link TemporalUnit#between}.
847     * The result of this method is a {@code long} representing the amount of
848     * the specified unit. By contrast, the result of {@code between} is an
849     * object that can be used directly in addition/subtraction:
850     * <pre>
851     *   long period = start.periodUntil(end, YEARS);   // this method
852     *   dateTime.plus(YEARS.between(start, end));      // use in plus/minus
853     * </pre>
854     * <p>
855     * The calculation is implemented in this method for {@link ChronoUnit}.
856     * The units {@code MONTHS}, {@code YEARS}, {@code DECADES},
857     * {@code CENTURIES}, {@code MILLENNIA} and {@code ERAS} are supported.
858     * Other {@code ChronoUnit} values will throw an exception.
859     * <p>
860     * If the unit is not a {@code ChronoUnit}, then the result of this method
861     * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)}
862     * passing {@code this} as the first argument and the input temporal as
863     * the second argument.
864     * <p>
865     * This instance is immutable and unaffected by this method call.
866     *
867     * @param endYearMonth  the end year-month, which must be a {@code YearMonth}, not null
868     * @param unit  the unit to measure the period in, not null
869     * @return the amount of the period between this year-month and the end year-month
870     * @throws DateTimeException if the period cannot be calculated
871     * @throws ArithmeticException if numeric overflow occurs
872     */
873    @Override
874    public long periodUntil(Temporal endYearMonth, TemporalUnit unit) {
875        if (endYearMonth instanceof YearMonth == false) {
876            Objects.requireNonNull(endYearMonth, "endYearMonth");
877            throw new DateTimeException("Unable to calculate period between objects of two different types");
878        }
879        YearMonth end = (YearMonth) endYearMonth;
880        if (unit instanceof ChronoUnit) {
881            long monthsUntil = end.getEpochMonth() - getEpochMonth();  // no overflow
882            switch ((ChronoUnit) unit) {
883                case MONTHS: return monthsUntil;
884                case YEARS: return monthsUntil / 12;
885                case DECADES: return monthsUntil / 120;
886                case CENTURIES: return monthsUntil / 1200;
887                case MILLENNIA: return monthsUntil / 12000;
888                case ERAS: return end.getLong(ERA) - getLong(ERA);
889            }
890            throw new DateTimeException("Unsupported unit: " + unit.getName());
891        }
892        return unit.between(this, endYearMonth).getAmount();
893    }
894
895    //-----------------------------------------------------------------------
896    /**
897     * Returns a date formed from this year-month at the specified day-of-month.
898     * <p>
899     * This combines this year-month and the specified day-of-month to form a {@code LocalDate}.
900     * The day-of-month value must be valid for the year-month.
901     * <p>
902     * This method can be used as part of a chain to produce a date:
903     * <pre>
904     *  LocalDate date = year.atMonth(month).atDay(day);
905     * </pre>
906     * <p>
907     * This instance is immutable and unaffected by this method call.
908     *
909     * @param dayOfMonth  the day-of-month to use, from 1 to 31
910     * @return the date formed from this year-month and the specified day, not null
911     * @throws DateTimeException when the day is invalid for the year-month
912     * @see #isValidDay(int)
913     */
914    public LocalDate atDay(int dayOfMonth) {
915        return LocalDate.of(year, month, dayOfMonth);
916    }
917
918    //-----------------------------------------------------------------------
919    /**
920     * Compares this year-month to another year-month.
921     * <p>
922     * The comparison is based first on the value of the year, then on the value of the month.
923     * It is "consistent with equals", as defined by {@link Comparable}.
924     *
925     * @param other  the other year-month to compare to, not null
926     * @return the comparator value, negative if less, positive if greater
927     */
928    @Override
929    public int compareTo(YearMonth other) {
930        int cmp = (year - other.year);
931        if (cmp == 0) {
932            cmp = (month - other.month);
933        }
934        return cmp;
935    }
936
937    /**
938     * Is this year-month after the specified year-month.
939     *
940     * @param other  the other year-month to compare to, not null
941     * @return true if this is after the specified year-month
942     */
943    public boolean isAfter(YearMonth other) {
944        return compareTo(other) > 0;
945    }
946
947    /**
948     * Is this year-month before the specified year-month.
949     *
950     * @param other  the other year-month to compare to, not null
951     * @return true if this point is before the specified year-month
952     */
953    public boolean isBefore(YearMonth other) {
954        return compareTo(other) < 0;
955    }
956
957    //-----------------------------------------------------------------------
958    /**
959     * Checks if this year-month is equal to another year-month.
960     * <p>
961     * The comparison is based on the time-line position of the year-months.
962     *
963     * @param obj  the object to check, null returns false
964     * @return true if this is equal to the other year-month
965     */
966    @Override
967    public boolean equals(Object obj) {
968        if (this == obj) {
969            return true;
970        }
971        if (obj instanceof YearMonth) {
972            YearMonth other = (YearMonth) obj;
973            return year == other.year && month == other.month;
974        }
975        return false;
976    }
977
978    /**
979     * A hash code for this year-month.
980     *
981     * @return a suitable hash code
982     */
983    @Override
984    public int hashCode() {
985        return year ^ (month << 27);
986    }
987
988    //-----------------------------------------------------------------------
989    /**
990     * Outputs this year-month as a {@code String}, such as {@code 2007-12}.
991     * <p>
992     * The output will be in the format {@code yyyy-MM}:
993     *
994     * @return a string representation of this year-month, not null
995     */
996    @Override
997    public String toString() {
998        int absYear = Math.abs(year);
999        StringBuilder buf = new StringBuilder(9);
1000        if (absYear < 1000) {
1001            if (year < 0) {
1002                buf.append(year - 10000).deleteCharAt(1);
1003            } else {
1004                buf.append(year + 10000).deleteCharAt(0);
1005            }
1006        } else {
1007            buf.append(year);
1008        }
1009        return buf.append(month < 10 ? "-0" : "-")
1010            .append(month)
1011            .toString();
1012    }
1013
1014    /**
1015     * Outputs this year-month as a {@code String} using the formatter.
1016     * <p>
1017     * This year-month will be passed to the formatter
1018     * {@link DateTimeFormatter#print(TemporalAccessor) print method}.
1019     *
1020     * @param formatter  the formatter to use, not null
1021     * @return the formatted year-month string, not null
1022     * @throws DateTimeException if an error occurs during printing
1023     */
1024    public String toString(DateTimeFormatter formatter) {
1025        Objects.requireNonNull(formatter, "formatter");
1026        return formatter.print(this);
1027    }
1028
1029    //-----------------------------------------------------------------------
1030    private Object writeReplace() {
1031        return new Ser(Ser.YEAR_MONTH_TYPE, this);
1032    }
1033
1034    /**
1035     * Defend against malicious streams.
1036     * @return never
1037     * @throws InvalidObjectException always
1038     */
1039    private Object readResolve() throws ObjectStreamException {
1040        throw new InvalidObjectException("Deserialization via serialization delegate");
1041    }
1042
1043    void writeExternal(DataOutput out) throws IOException {
1044        out.writeInt(year);
1045        out.writeByte(month);
1046    }
1047
1048    static YearMonth readExternal(DataInput in) throws IOException {
1049        int year = in.readInt();
1050        byte month = in.readByte();
1051        return YearMonth.of(year, month);
1052    }
1053
1054}