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