• 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.LocalTime.SECONDS_PER_DAY;
35 import static org.threeten.bp.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH;
36 import static org.threeten.bp.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR;
37 import static org.threeten.bp.temporal.ChronoField.ALIGNED_WEEK_OF_MONTH;
38 import static org.threeten.bp.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR;
39 import static org.threeten.bp.temporal.ChronoField.DAY_OF_MONTH;
40 import static org.threeten.bp.temporal.ChronoField.DAY_OF_YEAR;
41 import static org.threeten.bp.temporal.ChronoField.EPOCH_DAY;
42 import static org.threeten.bp.temporal.ChronoField.ERA;
43 import static org.threeten.bp.temporal.ChronoField.MONTH_OF_YEAR;
44 import static org.threeten.bp.temporal.ChronoField.PROLEPTIC_MONTH;
45 import static org.threeten.bp.temporal.ChronoField.YEAR;
46 
47 import java.io.DataInput;
48 import java.io.DataOutput;
49 import java.io.IOException;
50 import java.io.InvalidObjectException;
51 import java.io.ObjectStreamException;
52 import java.io.Serializable;
53 
54 import org.threeten.bp.chrono.ChronoLocalDate;
55 import org.threeten.bp.chrono.Era;
56 import org.threeten.bp.chrono.IsoChronology;
57 import org.threeten.bp.format.DateTimeFormatter;
58 import org.threeten.bp.format.DateTimeParseException;
59 import org.threeten.bp.jdk8.Jdk8Methods;
60 import org.threeten.bp.temporal.ChronoField;
61 import org.threeten.bp.temporal.ChronoUnit;
62 import org.threeten.bp.temporal.Temporal;
63 import org.threeten.bp.temporal.TemporalAccessor;
64 import org.threeten.bp.temporal.TemporalAdjuster;
65 import org.threeten.bp.temporal.TemporalAdjusters;
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 import org.threeten.bp.zone.ZoneOffsetTransition;
74 import org.threeten.bp.zone.ZoneRules;
75 
76 /**
77  * A date without a time-zone in the ISO-8601 calendar system,
78  * such as {@code 2007-12-23}.
79  * <p>
80  * {@code LocalDate} is an immutable date-time object that represents a date,
81  * often viewed as year-month-day. Other date fields, such as day-of-year,
82  * day-of-week and week-of-year, can also be accessed.
83  * For example, the value "2nd October 2007" can be stored in a {@code LocalDate}.
84  * <p>
85  * This class does not store or represent a time or time-zone.
86  * Instead, it is a description of the date, as used for birthdays.
87  * It cannot represent an instant on the time-line without additional information
88  * such as an offset or time-zone.
89  * <p>
90  * The ISO-8601 calendar system is the modern civil calendar system used today
91  * in most of the world. It is equivalent to the proleptic Gregorian calendar
92  * system, in which today's rules for leap years are applied for all time.
93  * For most applications written today, the ISO-8601 rules are entirely suitable.
94  * However, any application that makes use of historical dates, and requires them
95  * to be accurate will find the ISO-8601 approach unsuitable.
96  *
97  * <h3>Specification for implementors</h3>
98  * This class is immutable and thread-safe.
99  */
100 public final class LocalDate
101         extends ChronoLocalDate
102         implements Temporal, TemporalAdjuster, Serializable {
103 
104     /**
105      * The minimum supported {@code LocalDate}, '-999999999-01-01'.
106      * This could be used by an application as a "far past" date.
107      */
108     public static final LocalDate MIN = LocalDate.of(Year.MIN_VALUE, 1, 1);
109     /**
110      * The maximum supported {@code LocalDate}, '+999999999-12-31'.
111      * This could be used by an application as a "far future" date.
112      */
113     public static final LocalDate MAX = LocalDate.of(Year.MAX_VALUE, 12, 31);
114     /**
115      * Simulate JDK 8 method reference LocalDate::from.
116      */
117     public static final TemporalQuery<LocalDate> FROM = new TemporalQuery<LocalDate>() {
118         @Override
119         public LocalDate queryFrom(TemporalAccessor temporal) {
120             return LocalDate.from(temporal);
121         }
122     };
123 
124     /**
125      * Serialization version.
126      */
127     private static final long serialVersionUID = 2942565459149668126L;
128     /**
129      * The number of days in a 400 year cycle.
130      */
131     private static final int DAYS_PER_CYCLE = 146097;
132     /**
133      * The number of days from year zero to year 1970.
134      * There are five 400 year cycles from year zero to 2000.
135      * There are 7 leap years from 1970 to 2000.
136      */
137     static final long DAYS_0000_TO_1970 = (DAYS_PER_CYCLE * 5L) - (30L * 365L + 7L);
138 
139     /**
140      * The year.
141      */
142     private final int year;
143     /**
144      * The month-of-year.
145      */
146     private final short month;
147     /**
148      * The day-of-month.
149      */
150     private final short day;
151 
152     //-----------------------------------------------------------------------
153     /**
154      * Obtains the current date from the system clock in the default time-zone.
155      * <p>
156      * This will query the {@link Clock#systemDefaultZone() system clock} in the default
157      * time-zone to obtain the current date.
158      * <p>
159      * Using this method will prevent the ability to use an alternate clock for testing
160      * because the clock is hard-coded.
161      *
162      * @return the current date using the system clock and default time-zone, not null
163      */
now()164     public static LocalDate now() {
165         return now(Clock.systemDefaultZone());
166     }
167 
168     /**
169      * Obtains the current date from the system clock in the specified time-zone.
170      * <p>
171      * This will query the {@link Clock#system(ZoneId) system clock} to obtain the current date.
172      * Specifying the time-zone avoids dependence on the default time-zone.
173      * <p>
174      * Using this method will prevent the ability to use an alternate clock for testing
175      * because the clock is hard-coded.
176      *
177      * @param zone  the zone ID to use, not null
178      * @return the current date using the system clock, not null
179      */
now(ZoneId zone)180     public static LocalDate now(ZoneId zone) {
181         return now(Clock.system(zone));
182     }
183 
184     /**
185      * Obtains the current date from the specified clock.
186      * <p>
187      * This will query the specified clock to obtain the current date - today.
188      * Using this method allows the use of an alternate clock for testing.
189      * The alternate clock may be introduced using {@link Clock dependency injection}.
190      *
191      * @param clock  the clock to use, not null
192      * @return the current date, not null
193      */
now(Clock clock)194     public static LocalDate now(Clock clock) {
195         Jdk8Methods.requireNonNull(clock, "clock");
196         final Instant now = clock.instant();  // called once
197         ZoneOffset offset = clock.getZone().getRules().getOffset(now);
198         long epochSec = now.getEpochSecond() + offset.getTotalSeconds();  // overflow caught later
199         long epochDay = Jdk8Methods.floorDiv(epochSec, SECONDS_PER_DAY);
200         return LocalDate.ofEpochDay(epochDay);
201     }
202 
203     //-----------------------------------------------------------------------
204     /**
205      * Obtains an instance of {@code LocalDate} from a year, month and day.
206      * <p>
207      * The day must be valid for the year and month, otherwise an exception will be thrown.
208      *
209      * @param year  the year to represent, from MIN_YEAR to MAX_YEAR
210      * @param month  the month-of-year to represent, not null
211      * @param dayOfMonth  the day-of-month to represent, from 1 to 31
212      * @return the local date, not null
213      * @throws DateTimeException if the value of any field is out of range
214      * @throws DateTimeException if the day-of-month is invalid for the month-year
215      */
of(int year, Month month, int dayOfMonth)216     public static LocalDate of(int year, Month month, int dayOfMonth) {
217         YEAR.checkValidValue(year);
218         Jdk8Methods.requireNonNull(month, "month");
219         DAY_OF_MONTH.checkValidValue(dayOfMonth);
220         return create(year, month, dayOfMonth);
221     }
222 
223     /**
224      * Obtains an instance of {@code LocalDate} from a year, month and day.
225      * <p>
226      * The day must be valid for the year and month, otherwise an exception will be thrown.
227      *
228      * @param year  the year to represent, from MIN_YEAR to MAX_YEAR
229      * @param month  the month-of-year to represent, from 1 (January) to 12 (December)
230      * @param dayOfMonth  the day-of-month to represent, from 1 to 31
231      * @return the local date, not null
232      * @throws DateTimeException if the value of any field is out of range
233      * @throws DateTimeException if the day-of-month is invalid for the month-year
234      */
of(int year, int month, int dayOfMonth)235     public static LocalDate of(int year, int month, int dayOfMonth) {
236         YEAR.checkValidValue(year);
237         MONTH_OF_YEAR.checkValidValue(month);
238         DAY_OF_MONTH.checkValidValue(dayOfMonth);
239         return create(year, Month.of(month), dayOfMonth);
240     }
241 
242     //-----------------------------------------------------------------------
243     /**
244      * Obtains an instance of {@code LocalDate} from a year and day-of-year.
245      * <p>
246      * The day-of-year must be valid for the year, otherwise an exception will be thrown.
247      *
248      * @param year  the year to represent, from MIN_YEAR to MAX_YEAR
249      * @param dayOfYear  the day-of-year to represent, from 1 to 366
250      * @return the local date, not null
251      * @throws DateTimeException if the value of any field is out of range
252      * @throws DateTimeException if the day-of-year is invalid for the month-year
253      */
ofYearDay(int year, int dayOfYear)254     public static LocalDate ofYearDay(int year, int dayOfYear) {
255         YEAR.checkValidValue(year);
256         DAY_OF_YEAR.checkValidValue(dayOfYear);
257         boolean leap = IsoChronology.INSTANCE.isLeapYear(year);
258         if (dayOfYear == 366 && leap == false) {
259             throw new DateTimeException("Invalid date 'DayOfYear 366' as '" + year + "' is not a leap year");
260         }
261         Month moy = Month.of((dayOfYear - 1) / 31 + 1);
262         int monthEnd = moy.firstDayOfYear(leap) + moy.length(leap) - 1;
263         if (dayOfYear > monthEnd) {
264             moy = moy.plus(1);
265         }
266         int dom = dayOfYear - moy.firstDayOfYear(leap) + 1;
267         return create(year, moy, dom);
268     }
269 
270     //-----------------------------------------------------------------------
271     /**
272      * Obtains an instance of {@code LocalDate} from the epoch day count.
273      * <p>
274      * The Epoch Day count is a simple incrementing count of days
275      * where day 0 is 1970-01-01. Negative numbers represent earlier days.
276      *
277      * @param epochDay  the Epoch Day to convert, based on the epoch 1970-01-01
278      * @return the local date, not null
279      * @throws DateTimeException if the epoch days exceeds the supported date range
280      */
ofEpochDay(long epochDay)281     public static LocalDate ofEpochDay(long epochDay) {
282         EPOCH_DAY.checkValidValue(epochDay);
283         long zeroDay = epochDay + DAYS_0000_TO_1970;
284         // find the march-based year
285         zeroDay -= 60;  // adjust to 0000-03-01 so leap day is at end of four year cycle
286         long adjust = 0;
287         if (zeroDay < 0) {
288             // adjust negative years to positive for calculation
289             long adjustCycles = (zeroDay + 1) / DAYS_PER_CYCLE - 1;
290             adjust = adjustCycles * 400;
291             zeroDay += -adjustCycles * DAYS_PER_CYCLE;
292         }
293         long yearEst = (400 * zeroDay + 591) / DAYS_PER_CYCLE;
294         long doyEst = zeroDay - (365 * yearEst + yearEst / 4 - yearEst / 100 + yearEst / 400);
295         if (doyEst < 0) {
296             // fix estimate
297             yearEst--;
298             doyEst = zeroDay - (365 * yearEst + yearEst / 4 - yearEst / 100 + yearEst / 400);
299         }
300         yearEst += adjust;  // reset any negative year
301         int marchDoy0 = (int) doyEst;
302 
303         // convert march-based values back to january-based
304         int marchMonth0 = (marchDoy0 * 5 + 2) / 153;
305         int month = (marchMonth0 + 2) % 12 + 1;
306         int dom = marchDoy0 - (marchMonth0 * 306 + 5) / 10 + 1;
307         yearEst += marchMonth0 / 10;
308 
309         // check year now we are certain it is correct
310         int year = YEAR.checkValidIntValue(yearEst);
311         return new LocalDate(year, month, dom);
312     }
313 
314     //-----------------------------------------------------------------------
315     /**
316      * Obtains an instance of {@code LocalDate} from a temporal object.
317      * <p>
318      * A {@code TemporalAccessor} represents some form of date and time information.
319      * This factory converts the arbitrary temporal object to an instance of {@code LocalDate}.
320      * <p>
321      * The conversion uses the {@link TemporalQueries#localDate()} query, which relies
322      * on extracting the {@link ChronoField#EPOCH_DAY EPOCH_DAY} field.
323      * <p>
324      * This method matches the signature of the functional interface {@link TemporalQuery}
325      * allowing it to be used as a query via method reference, {@code LocalDate::from}.
326      *
327      * @param temporal  the temporal object to convert, not null
328      * @return the local date, not null
329      * @throws DateTimeException if unable to convert to a {@code LocalDate}
330      */
from(TemporalAccessor temporal)331     public static LocalDate from(TemporalAccessor temporal) {
332         LocalDate date = temporal.query(TemporalQueries.localDate());
333         if (date == null) {
334             throw new DateTimeException("Unable to obtain LocalDate from TemporalAccessor: " +
335                     temporal + ", type " + temporal.getClass().getName());
336         }
337         return date;
338     }
339 
340     //-----------------------------------------------------------------------
341     /**
342      * Obtains an instance of {@code LocalDate} from a text string such as {@code 2007-12-23}.
343      * <p>
344      * The string must represent a valid date and is parsed using
345      * {@link org.threeten.bp.format.DateTimeFormatter#ISO_LOCAL_DATE}.
346      *
347      * @param text  the text to parse such as "2007-12-23", not null
348      * @return the parsed local date, not null
349      * @throws DateTimeParseException if the text cannot be parsed
350      */
parse(CharSequence text)351     public static LocalDate parse(CharSequence text) {
352         return parse(text, DateTimeFormatter.ISO_LOCAL_DATE);
353     }
354 
355     /**
356      * Obtains an instance of {@code LocalDate} from a text string using a specific formatter.
357      * <p>
358      * The text is parsed using the formatter, returning a date.
359      *
360      * @param text  the text to parse, not null
361      * @param formatter  the formatter to use, not null
362      * @return the parsed local date, not null
363      * @throws DateTimeParseException if the text cannot be parsed
364      */
parse(CharSequence text, DateTimeFormatter formatter)365     public static LocalDate parse(CharSequence text, DateTimeFormatter formatter) {
366         Jdk8Methods.requireNonNull(formatter, "formatter");
367         return formatter.parse(text, LocalDate.FROM);
368     }
369 
370     //-----------------------------------------------------------------------
371     /**
372      * Creates a local date from the year, month and day fields.
373      *
374      * @param year  the year to represent, validated from MIN_YEAR to MAX_YEAR
375      * @param month  the month-of-year to represent, validated not null
376      * @param dayOfMonth  the day-of-month to represent, validated from 1 to 31
377      * @return the local date, not null
378      * @throws DateTimeException if the day-of-month is invalid for the month-year
379      */
create(int year, Month month, int dayOfMonth)380     private static LocalDate create(int year, Month month, int dayOfMonth) {
381         if (dayOfMonth > 28 && dayOfMonth > month.length(IsoChronology.INSTANCE.isLeapYear(year))) {
382             if (dayOfMonth == 29) {
383                 throw new DateTimeException("Invalid date 'February 29' as '" + year + "' is not a leap year");
384             } else {
385                 throw new DateTimeException("Invalid date '" + month.name() + " " + dayOfMonth + "'");
386             }
387         }
388         return new LocalDate(year, month.getValue(), dayOfMonth);
389     }
390 
391     /**
392      * Resolves the date, resolving days past the end of month.
393      *
394      * @param year  the year to represent, validated from MIN_YEAR to MAX_YEAR
395      * @param month  the month-of-year to represent, validated from 1 to 12
396      * @param day  the day-of-month to represent, validated from 1 to 31
397      * @return the resolved date, not null
398      */
resolvePreviousValid(int year, int month, int day)399     private static LocalDate resolvePreviousValid(int year, int month, int day) {
400         switch (month) {
401             case 2:
402                 day = Math.min(day, IsoChronology.INSTANCE.isLeapYear(year) ? 29 : 28);
403                 break;
404             case 4:
405             case 6:
406             case 9:
407             case 11:
408                 day = Math.min(day, 30);
409                 break;
410         }
411         return LocalDate.of(year, month, day);
412     }
413 
414     /**
415      * Constructor, previously validated.
416      *
417      * @param year  the year to represent, from MIN_YEAR to MAX_YEAR
418      * @param month  the month-of-year to represent, not null
419      * @param dayOfMonth  the day-of-month to represent, valid for year-month, from 1 to 31
420      */
LocalDate(int year, int month, int dayOfMonth)421     private LocalDate(int year, int month, int dayOfMonth) {
422         this.year = year;
423         this.month = (short) month;
424         this.day = (short) dayOfMonth;
425     }
426 
427     //-----------------------------------------------------------------------
428     /**
429      * Checks if the specified field is supported.
430      * <p>
431      * This checks if this date can be queried for the specified field.
432      * If false, then calling the {@link #range(TemporalField) range} and
433      * {@link #get(TemporalField) get} methods will throw an exception.
434      * <p>
435      * If the field is a {@link ChronoField} then the query is implemented here.
436      * The {@link #isSupported(TemporalField) supported fields} will return valid
437      * values based on this date-time.
438      * The supported fields are:
439      * <ul>
440      * <li>{@code DAY_OF_WEEK}
441      * <li>{@code ALIGNED_DAY_OF_WEEK_IN_MONTH}
442      * <li>{@code ALIGNED_DAY_OF_WEEK_IN_YEAR}
443      * <li>{@code DAY_OF_MONTH}
444      * <li>{@code DAY_OF_YEAR}
445      * <li>{@code EPOCH_DAY}
446      * <li>{@code ALIGNED_WEEK_OF_MONTH}
447      * <li>{@code ALIGNED_WEEK_OF_YEAR}
448      * <li>{@code MONTH_OF_YEAR}
449      * <li>{@code EPOCH_MONTH}
450      * <li>{@code YEAR_OF_ERA}
451      * <li>{@code YEAR}
452      * <li>{@code ERA}
453      * </ul>
454      * All other {@code ChronoField} instances will return false.
455      * <p>
456      * If the field is not a {@code ChronoField}, then the result of this method
457      * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
458      * passing {@code this} as the argument.
459      * Whether the field is supported is determined by the field.
460      *
461      * @param field  the field to check, null returns false
462      * @return true if the field is supported on this date, false if not
463      */
464     @Override  // override for Javadoc
isSupported(TemporalField field)465     public boolean isSupported(TemporalField field) {
466         return super.isSupported(field);
467     }
468 
469     /**
470      * Gets the range of valid values for the specified field.
471      * <p>
472      * The range object expresses the minimum and maximum valid values for a field.
473      * This date is used to enhance the accuracy of the returned range.
474      * If it is not possible to return the range, because the field is not supported
475      * or for some other reason, an exception is thrown.
476      * <p>
477      * If the field is a {@link ChronoField} then the query is implemented here.
478      * The {@link #isSupported(TemporalField) supported fields} will return
479      * appropriate range instances.
480      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
481      * <p>
482      * If the field is not a {@code ChronoField}, then the result of this method
483      * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
484      * passing {@code this} as the argument.
485      * Whether the range can be obtained is determined by the field.
486      *
487      * @param field  the field to query the range for, not null
488      * @return the range of valid values for the field, not null
489      * @throws DateTimeException if the range for the field cannot be obtained
490      */
491     @Override
range(TemporalField field)492     public ValueRange range(TemporalField field) {
493         if (field instanceof ChronoField) {
494             ChronoField f = (ChronoField) field;
495             if (f.isDateBased()) {
496                 switch (f) {
497                     case DAY_OF_MONTH: return ValueRange.of(1, lengthOfMonth());
498                     case DAY_OF_YEAR: return ValueRange.of(1, lengthOfYear());
499                     case ALIGNED_WEEK_OF_MONTH: return ValueRange.of(1, getMonth() == Month.FEBRUARY && isLeapYear() == false ? 4 : 5);
500                     case YEAR_OF_ERA:
501                         return (getYear() <= 0 ? ValueRange.of(1, Year.MAX_VALUE + 1) : ValueRange.of(1, Year.MAX_VALUE));
502                 }
503                 return field.range();
504             }
505             throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
506         }
507         return field.rangeRefinedBy(this);
508     }
509 
510     /**
511      * Gets the value of the specified field from this date as an {@code int}.
512      * <p>
513      * This queries this date for the value for the specified field.
514      * The returned value will always be within the valid range of values for the field.
515      * If it is not possible to return the value, because the field is not supported
516      * or for some other reason, an exception is thrown.
517      * <p>
518      * If the field is a {@link ChronoField} then the query is implemented here.
519      * The {@link #isSupported(TemporalField) supported fields} will return valid
520      * values based on this date, except {@code EPOCH_DAY} and {@code EPOCH_MONTH}
521      * which are too large to fit in an {@code int} and throw a {@code DateTimeException}.
522      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
523      * <p>
524      * If the field is not a {@code ChronoField}, then the result of this method
525      * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
526      * passing {@code this} as the argument. Whether the value can be obtained,
527      * and what the value represents, is determined by the field.
528      *
529      * @param field  the field to get, not null
530      * @return the value for the field
531      * @throws DateTimeException if a value for the field cannot be obtained
532      * @throws ArithmeticException if numeric overflow occurs
533      */
534     @Override  // override for Javadoc and performance
get(TemporalField field)535     public int get(TemporalField field) {
536         if (field instanceof ChronoField) {
537             return get0(field);
538         }
539         return super.get(field);
540     }
541 
542     /**
543      * Gets the value of the specified field from this date as a {@code long}.
544      * <p>
545      * This queries this date for the value for the specified field.
546      * If it is not possible to return the value, because the field is not supported
547      * or for some other reason, an exception is thrown.
548      * <p>
549      * If the field is a {@link ChronoField} then the query is implemented here.
550      * The {@link #isSupported(TemporalField) supported fields} will return valid
551      * values based on this date.
552      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
553      * <p>
554      * If the field is not a {@code ChronoField}, then the result of this method
555      * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
556      * passing {@code this} as the argument. Whether the value can be obtained,
557      * and what the value represents, is determined by the field.
558      *
559      * @param field  the field to get, not null
560      * @return the value for the field
561      * @throws DateTimeException if a value for the field cannot be obtained
562      * @throws ArithmeticException if numeric overflow occurs
563      */
564     @Override
getLong(TemporalField field)565     public long getLong(TemporalField field) {
566         if (field instanceof ChronoField) {
567             if (field == EPOCH_DAY) {
568                 return toEpochDay();
569             }
570             if (field == PROLEPTIC_MONTH) {
571                 return getProlepticMonth();
572             }
573             return get0(field);
574         }
575         return field.getFrom(this);
576     }
577 
get0(TemporalField field)578     private int get0(TemporalField field) {
579         switch ((ChronoField) field) {
580             case DAY_OF_WEEK: return getDayOfWeek().getValue();
581             case ALIGNED_DAY_OF_WEEK_IN_MONTH: return ((day - 1) % 7) + 1;
582             case ALIGNED_DAY_OF_WEEK_IN_YEAR: return ((getDayOfYear() - 1) % 7) + 1;
583             case DAY_OF_MONTH: return day;
584             case DAY_OF_YEAR: return getDayOfYear();
585             case EPOCH_DAY: throw new DateTimeException("Field too large for an int: " + field);
586             case ALIGNED_WEEK_OF_MONTH: return ((day - 1) / 7) + 1;
587             case ALIGNED_WEEK_OF_YEAR: return ((getDayOfYear() - 1) / 7) + 1;
588             case MONTH_OF_YEAR: return month;
589             case PROLEPTIC_MONTH: throw new DateTimeException("Field too large for an int: " + field);
590             case YEAR_OF_ERA: return (year >= 1 ? year : 1 - year);
591             case YEAR: return year;
592             case ERA: return (year >= 1 ? 1 : 0);
593         }
594         throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
595     }
596 
getProlepticMonth()597     private long getProlepticMonth() {
598         return (year * 12L) + (month - 1);
599     }
600 
601     //-----------------------------------------------------------------------
602     /**
603      * Gets the chronology of this date, which is the ISO calendar system.
604      * <p>
605      * The {@code Chronology} represents the calendar system in use.
606      * The ISO-8601 calendar system is the modern civil calendar system used today
607      * in most of the world. It is equivalent to the proleptic Gregorian calendar
608      * system, in which todays's rules for leap years are applied for all time.
609      *
610      * @return the ISO chronology, not null
611      */
612     @Override
getChronology()613     public IsoChronology getChronology() {
614         return IsoChronology.INSTANCE;
615     }
616 
617     /**
618      * Gets the era applicable at this date.
619      * <p>
620      * The official ISO-8601 standard does not define eras, however {@code IsoChronology} does.
621      * It defines two eras, 'CE' from year one onwards and 'BCE' from year zero backwards.
622      * Since dates before the Julian-Gregorian cutover are not in line with history,
623      * the cutover between 'BCE' and 'CE' is also not aligned with the commonly used
624      * eras, often referred to using 'BC' and 'AD'.
625      * <p>
626      * Users of this class should typically ignore this method as it exists primarily
627      * to fulfill the {@link ChronoLocalDate} contract where it is necessary to support
628      * the Japanese calendar system.
629      * <p>
630      * The returned era will be a singleton capable of being compared with the constants
631      * in {@link IsoChronology} using the {@code ==} operator.
632      *
633      * @return the {@code IsoChronology} era constant applicable at this date, not null
634      */
635     @Override // override for Javadoc
getEra()636     public Era getEra() {
637         return super.getEra();
638     }
639 
640     /**
641      * Gets the year field.
642      * <p>
643      * This method returns the primitive {@code int} value for the year.
644      * <p>
645      * The year returned by this method is proleptic as per {@code get(YEAR)}.
646      * To obtain the year-of-era, use {@code get(YEAR_OF_ERA}.
647      *
648      * @return the year, from MIN_YEAR to MAX_YEAR
649      */
getYear()650     public int getYear() {
651         return year;
652     }
653 
654     /**
655      * Gets the month-of-year field from 1 to 12.
656      * <p>
657      * This method returns the month as an {@code int} from 1 to 12.
658      * Application code is frequently clearer if the enum {@link Month}
659      * is used by calling {@link #getMonth()}.
660      *
661      * @return the month-of-year, from 1 to 12
662      * @see #getMonth()
663      */
getMonthValue()664     public int getMonthValue() {
665         return month;
666     }
667 
668     /**
669      * Gets the month-of-year field using the {@code Month} enum.
670      * <p>
671      * This method returns the enum {@link Month} for the month.
672      * This avoids confusion as to what {@code int} values mean.
673      * If you need access to the primitive {@code int} value then the enum
674      * provides the {@link Month#getValue() int value}.
675      *
676      * @return the month-of-year, not null
677      * @see #getMonthValue()
678      */
getMonth()679     public Month getMonth() {
680         return Month.of(month);
681     }
682 
683     /**
684      * Gets the day-of-month field.
685      * <p>
686      * This method returns the primitive {@code int} value for the day-of-month.
687      *
688      * @return the day-of-month, from 1 to 31
689      */
getDayOfMonth()690     public int getDayOfMonth() {
691         return day;
692     }
693 
694     /**
695      * Gets the day-of-year field.
696      * <p>
697      * This method returns the primitive {@code int} value for the day-of-year.
698      *
699      * @return the day-of-year, from 1 to 365, or 366 in a leap year
700      */
getDayOfYear()701     public int getDayOfYear() {
702         return getMonth().firstDayOfYear(isLeapYear()) + day - 1;
703     }
704 
705     /**
706      * Gets the day-of-week field, which is an enum {@code DayOfWeek}.
707      * <p>
708      * This method returns the enum {@link DayOfWeek} for the day-of-week.
709      * This avoids confusion as to what {@code int} values mean.
710      * If you need access to the primitive {@code int} value then the enum
711      * provides the {@link DayOfWeek#getValue() int value}.
712      * <p>
713      * Additional information can be obtained from the {@code DayOfWeek}.
714      * This includes textual names of the values.
715      *
716      * @return the day-of-week, not null
717      */
getDayOfWeek()718     public DayOfWeek getDayOfWeek() {
719         int dow0 = Jdk8Methods.floorMod(toEpochDay() + 3, 7);
720         return DayOfWeek.of(dow0 + 1);
721     }
722 
723     //-----------------------------------------------------------------------
724     /**
725      * Checks if the year is a leap year, according to the ISO proleptic
726      * calendar system rules.
727      * <p>
728      * This method applies the current rules for leap years across the whole time-line.
729      * In general, a year is a leap year if it is divisible by four without
730      * remainder. However, years divisible by 100, are not leap years, with
731      * the exception of years divisible by 400 which are.
732      * <p>
733      * For example, 1904 is a leap year it is divisible by 4.
734      * 1900 was not a leap year as it is divisible by 100, however 2000 was a
735      * leap year as it is divisible by 400.
736      * <p>
737      * The calculation is proleptic - applying the same rules into the far future and far past.
738      * This is historically inaccurate, but is correct for the ISO-8601 standard.
739      *
740      * @return true if the year is leap, false otherwise
741      */
742     @Override // override for Javadoc and performance
isLeapYear()743     public boolean isLeapYear() {
744         return IsoChronology.INSTANCE.isLeapYear(year);
745     }
746 
747     /**
748      * Returns the length of the month represented by this date.
749      * <p>
750      * This returns the length of the month in days.
751      * For example, a date in January would return 31.
752      *
753      * @return the length of the month in days
754      */
755     @Override
lengthOfMonth()756     public int lengthOfMonth() {
757         switch (month) {
758             case 2:
759                 return (isLeapYear() ? 29 : 28);
760             case 4:
761             case 6:
762             case 9:
763             case 11:
764                 return 30;
765             default:
766                 return 31;
767         }
768     }
769 
770     /**
771      * Returns the length of the year represented by this date.
772      * <p>
773      * This returns the length of the year in days, either 365 or 366.
774      *
775      * @return 366 if the year is leap, 365 otherwise
776      */
777     @Override // override for Javadoc and performance
lengthOfYear()778     public int lengthOfYear() {
779         return (isLeapYear() ? 366 : 365);
780     }
781 
782     //-----------------------------------------------------------------------
783     /**
784      * Returns an adjusted copy of this date.
785      * <p>
786      * This returns a new {@code LocalDate}, based on this one, with the date adjusted.
787      * The adjustment takes place using the specified adjuster strategy object.
788      * Read the documentation of the adjuster to understand what adjustment will be made.
789      * <p>
790      * A simple adjuster might simply set the one of the fields, such as the year field.
791      * A more complex adjuster might set the date to the last day of the month.
792      * A selection of common adjustments is provided in {@link TemporalAdjusters}.
793      * These include finding the "last day of the month" and "next Wednesday".
794      * Key date-time classes also implement the {@code TemporalAdjuster} interface,
795      * such as {@link Month} and {@link MonthDay}.
796      * The adjuster is responsible for handling special cases, such as the varying
797      * lengths of month and leap years.
798      * <p>
799      * For example this code returns a date on the last day of July:
800      * <pre>
801      *  import static org.threeten.bp.Month.*;
802      *  import static org.threeten.bp.temporal.Adjusters.*;
803      *
804      *  result = localDate.with(JULY).with(lastDayOfMonth());
805      * </pre>
806      * <p>
807      * The result of this method is obtained by invoking the
808      * {@link TemporalAdjuster#adjustInto(Temporal)} method on the
809      * specified adjuster passing {@code this} as the argument.
810      * <p>
811      * This instance is immutable and unaffected by this method call.
812      *
813      * @param adjuster the adjuster to use, not null
814      * @return a {@code LocalDate} based on {@code this} with the adjustment made, not null
815      * @throws DateTimeException if the adjustment cannot be made
816      * @throws ArithmeticException if numeric overflow occurs
817      */
818     @Override
with(TemporalAdjuster adjuster)819     public LocalDate with(TemporalAdjuster adjuster) {
820         // optimizations
821         if (adjuster instanceof LocalDate) {
822             return (LocalDate) adjuster;
823         }
824         return (LocalDate) adjuster.adjustInto(this);
825     }
826 
827     /**
828      * Returns a copy of this date with the specified field set to a new value.
829      * <p>
830      * This returns a new {@code LocalDate}, based on this one, with the value
831      * for the specified field changed.
832      * This can be used to change any supported field, such as the year, month or day-of-month.
833      * If it is not possible to set the value, because the field is not supported or for
834      * some other reason, an exception is thrown.
835      * <p>
836      * In some cases, changing the specified field can cause the resulting date to become invalid,
837      * such as changing the month from 31st January to February would make the day-of-month invalid.
838      * In cases like this, the field is responsible for resolving the date. Typically it will choose
839      * the previous valid date, which would be the last valid day of February in this example.
840      * <p>
841      * If the field is a {@link ChronoField} then the adjustment is implemented here.
842      * The supported fields behave as follows:
843      * <ul>
844      * <li>{@code DAY_OF_WEEK} -
845      *  Returns a {@code LocalDate} with the specified day-of-week.
846      *  The date is adjusted up to 6 days forward or backward within the boundary
847      *  of a Monday to Sunday week.
848      * <li>{@code ALIGNED_DAY_OF_WEEK_IN_MONTH} -
849      *  Returns a {@code LocalDate} with the specified aligned-day-of-week.
850      *  The date is adjusted to the specified month-based aligned-day-of-week.
851      *  Aligned weeks are counted such that the first week of a given month starts
852      *  on the first day of that month.
853      *  This may cause the date to be moved up to 6 days into the following month.
854      * <li>{@code ALIGNED_DAY_OF_WEEK_IN_YEAR} -
855      *  Returns a {@code LocalDate} with the specified aligned-day-of-week.
856      *  The date is adjusted to the specified year-based aligned-day-of-week.
857      *  Aligned weeks are counted such that the first week of a given year starts
858      *  on the first day of that year.
859      *  This may cause the date to be moved up to 6 days into the following year.
860      * <li>{@code DAY_OF_MONTH} -
861      *  Returns a {@code LocalDate} with the specified day-of-month.
862      *  The month and year will be unchanged. If the day-of-month is invalid for the
863      *  year and month, then a {@code DateTimeException} is thrown.
864      * <li>{@code DAY_OF_YEAR} -
865      *  Returns a {@code LocalDate} with the specified day-of-year.
866      *  The year will be unchanged. If the day-of-year is invalid for the
867      *  year, then a {@code DateTimeException} is thrown.
868      * <li>{@code EPOCH_DAY} -
869      *  Returns a {@code LocalDate} with the specified epoch-day.
870      *  This completely replaces the date and is equivalent to {@link #ofEpochDay(long)}.
871      * <li>{@code ALIGNED_WEEK_OF_MONTH} -
872      *  Returns a {@code LocalDate} with the specified aligned-week-of-month.
873      *  Aligned weeks are counted such that the first week of a given month starts
874      *  on the first day of that month.
875      *  This adjustment moves the date in whole week chunks to match the specified week.
876      *  The result will have the same day-of-week as this date.
877      *  This may cause the date to be moved into the following month.
878      * <li>{@code ALIGNED_WEEK_OF_YEAR} -
879      *  Returns a {@code LocalDate} with the specified aligned-week-of-year.
880      *  Aligned weeks are counted such that the first week of a given year starts
881      *  on the first day of that year.
882      *  This adjustment moves the date in whole week chunks to match the specified week.
883      *  The result will have the same day-of-week as this date.
884      *  This may cause the date to be moved into the following year.
885      * <li>{@code MONTH_OF_YEAR} -
886      *  Returns a {@code LocalDate} with the specified month-of-year.
887      *  The year will be unchanged. The day-of-month will also be unchanged,
888      *  unless it would be invalid for the new month and year. In that case, the
889      *  day-of-month is adjusted to the maximum valid value for the new month and year.
890      * <li>{@code PROLEPTIC_MONTH} -
891      *  Returns a {@code LocalDate} with the specified proleptic-month.
892      *  The day-of-month will be unchanged, unless it would be invalid for the new month
893      *  and year. In that case, the day-of-month is adjusted to the maximum valid value
894      *  for the new month and year.
895      * <li>{@code YEAR_OF_ERA} -
896      *  Returns a {@code LocalDate} with the specified year-of-era.
897      *  The era and month will be unchanged. The day-of-month will also be unchanged,
898      *  unless it would be invalid for the new month and year. In that case, the
899      *  day-of-month is adjusted to the maximum valid value for the new month and year.
900      * <li>{@code YEAR} -
901      *  Returns a {@code LocalDate} with the specified year.
902      *  The month will be unchanged. The day-of-month will also be unchanged,
903      *  unless it would be invalid for the new month and year. In that case, the
904      *  day-of-month is adjusted to the maximum valid value for the new month and year.
905      * <li>{@code ERA} -
906      *  Returns a {@code LocalDate} with the specified era.
907      *  The year-of-era and month will be unchanged. The day-of-month will also be unchanged,
908      *  unless it would be invalid for the new month and year. In that case, the
909      *  day-of-month is adjusted to the maximum valid value for the new month and year.
910      * </ul>
911      * <p>
912      * In all cases, if the new value is outside the valid range of values for the field
913      * then a {@code DateTimeException} will be thrown.
914      * <p>
915      * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
916      * <p>
917      * If the field is not a {@code ChronoField}, then the result of this method
918      * is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)}
919      * passing {@code this} as the argument. In this case, the field determines
920      * whether and how to adjust the instant.
921      * <p>
922      * This instance is immutable and unaffected by this method call.
923      *
924      * @param field  the field to set in the result, not null
925      * @param newValue  the new value of the field in the result
926      * @return a {@code LocalDate} based on {@code this} with the specified field set, not null
927      * @throws DateTimeException if the field cannot be set
928      * @throws ArithmeticException if numeric overflow occurs
929      */
930     @Override
with(TemporalField field, long newValue)931     public LocalDate with(TemporalField field, long newValue) {
932         if (field instanceof ChronoField) {
933             ChronoField f = (ChronoField) field;
934             f.checkValidValue(newValue);
935             switch (f) {
936                 case DAY_OF_WEEK: return plusDays(newValue - getDayOfWeek().getValue());
937                 case ALIGNED_DAY_OF_WEEK_IN_MONTH: return plusDays(newValue - getLong(ALIGNED_DAY_OF_WEEK_IN_MONTH));
938                 case ALIGNED_DAY_OF_WEEK_IN_YEAR: return plusDays(newValue - getLong(ALIGNED_DAY_OF_WEEK_IN_YEAR));
939                 case DAY_OF_MONTH: return withDayOfMonth((int) newValue);
940                 case DAY_OF_YEAR: return withDayOfYear((int) newValue);
941                 case EPOCH_DAY: return LocalDate.ofEpochDay(newValue);
942                 case ALIGNED_WEEK_OF_MONTH: return plusWeeks(newValue - getLong(ALIGNED_WEEK_OF_MONTH));
943                 case ALIGNED_WEEK_OF_YEAR: return plusWeeks(newValue - getLong(ALIGNED_WEEK_OF_YEAR));
944                 case MONTH_OF_YEAR: return withMonth((int) newValue);
945                 case PROLEPTIC_MONTH: return plusMonths(newValue - getLong(PROLEPTIC_MONTH));
946                 case YEAR_OF_ERA: return withYear((int) (year >= 1 ? newValue : 1 - newValue));
947                 case YEAR: return withYear((int) newValue);
948                 case ERA: return (getLong(ERA) == newValue ? this : withYear(1 - year));
949             }
950             throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
951         }
952         return field.adjustInto(this, newValue);
953     }
954 
955     //-----------------------------------------------------------------------
956     /**
957      * Returns a copy of this date with the year altered.
958      * If the day-of-month is invalid for the year, it will be changed to the last valid day of the month.
959      * <p>
960      * This instance is immutable and unaffected by this method call.
961      *
962      * @param year  the year to set in the result, from MIN_YEAR to MAX_YEAR
963      * @return a {@code LocalDate} based on this date with the requested year, not null
964      * @throws DateTimeException if the year value is invalid
965      */
withYear(int year)966     public LocalDate withYear(int year) {
967         if (this.year == year) {
968             return this;
969         }
970         YEAR.checkValidValue(year);
971         return resolvePreviousValid(year, month, day);
972     }
973 
974     /**
975      * Returns a copy of this date with the month-of-year altered.
976      * If the day-of-month is invalid for the year, it will be changed to the last valid day of the month.
977      * <p>
978      * This instance is immutable and unaffected by this method call.
979      *
980      * @param month  the month-of-year to set in the result, from 1 (January) to 12 (December)
981      * @return a {@code LocalDate} based on this date with the requested month, not null
982      * @throws DateTimeException if the month-of-year value is invalid
983      */
withMonth(int month)984     public LocalDate withMonth(int month) {
985         if (this.month == month) {
986             return this;
987         }
988         MONTH_OF_YEAR.checkValidValue(month);
989         return resolvePreviousValid(year, month, day);
990     }
991 
992     /**
993      * Returns a copy of this date with the day-of-month altered.
994      * If the resulting date is invalid, an exception is thrown.
995      * <p>
996      * This instance is immutable and unaffected by this method call.
997      *
998      * @param dayOfMonth  the day-of-month to set in the result, from 1 to 28-31
999      * @return a {@code LocalDate} based on this date with the requested day, not null
1000      * @throws DateTimeException if the day-of-month value is invalid
1001      * @throws DateTimeException if the day-of-month is invalid for the month-year
1002      */
withDayOfMonth(int dayOfMonth)1003     public LocalDate withDayOfMonth(int dayOfMonth) {
1004         if (this.day == dayOfMonth) {
1005             return this;
1006         }
1007         return of(year, month, dayOfMonth);
1008     }
1009 
1010     /**
1011      * Returns a copy of this date with the day-of-year altered.
1012      * If the resulting date is invalid, an exception is thrown.
1013      * <p>
1014      * This instance is immutable and unaffected by this method call.
1015      *
1016      * @param dayOfYear  the day-of-year to set in the result, from 1 to 365-366
1017      * @return a {@code LocalDate} based on this date with the requested day, not null
1018      * @throws DateTimeException if the day-of-year value is invalid
1019      * @throws DateTimeException if the day-of-year is invalid for the year
1020      */
withDayOfYear(int dayOfYear)1021     public LocalDate withDayOfYear(int dayOfYear) {
1022         if (this.getDayOfYear() == dayOfYear) {
1023             return this;
1024         }
1025         return ofYearDay(year, dayOfYear);
1026     }
1027 
1028     //-----------------------------------------------------------------------
1029     /**
1030      * Returns a copy of this date with the specified period added.
1031      * <p>
1032      * This method returns a new date based on this date with the specified period added.
1033      * The amount is typically {@link Period} but may be any other type implementing
1034      * the {@link TemporalAmount} interface.
1035      * The calculation is delegated to the specified adjuster, which typically calls
1036      * back to {@link #plus(long, TemporalUnit)}.
1037      * <p>
1038      * This instance is immutable and unaffected by this method call.
1039      *
1040      * @param amount  the amount to add, not null
1041      * @return a {@code LocalDate} based on this date with the addition made, not null
1042      * @throws DateTimeException if the addition cannot be made
1043      * @throws ArithmeticException if numeric overflow occurs
1044      */
1045     @Override
plus(TemporalAmount amount)1046     public LocalDate plus(TemporalAmount amount) {
1047         return (LocalDate) amount.addTo(this);
1048     }
1049 
1050     /**
1051      * Returns a copy of this date with the specified period added.
1052      * <p>
1053      * This method returns a new date based on this date with the specified period added.
1054      * This can be used to add any period that is defined by a unit, for example to add years, months or days.
1055      * The unit is responsible for the details of the calculation, including the resolution
1056      * of any edge cases in the calculation.
1057      * <p>
1058      * This instance is immutable and unaffected by this method call.
1059      *
1060      * @param amountToAdd  the amount of the unit to add to the result, may be negative
1061      * @param unit  the unit of the period to add, not null
1062      * @return a {@code LocalDate} based on this date with the specified period added, not null
1063      * @throws DateTimeException if the unit cannot be added to this type
1064      */
1065     @Override
plus(long amountToAdd, TemporalUnit unit)1066     public LocalDate plus(long amountToAdd, TemporalUnit unit) {
1067         if (unit instanceof ChronoUnit) {
1068             ChronoUnit f = (ChronoUnit) unit;
1069             switch (f) {
1070                 case DAYS: return plusDays(amountToAdd);
1071                 case WEEKS: return plusWeeks(amountToAdd);
1072                 case MONTHS: return plusMonths(amountToAdd);
1073                 case YEARS: return plusYears(amountToAdd);
1074                 case DECADES: return plusYears(Jdk8Methods.safeMultiply(amountToAdd, 10));
1075                 case CENTURIES: return plusYears(Jdk8Methods.safeMultiply(amountToAdd, 100));
1076                 case MILLENNIA: return plusYears(Jdk8Methods.safeMultiply(amountToAdd, 1000));
1077                 case ERAS: return with(ERA, Jdk8Methods.safeAdd(getLong(ERA), amountToAdd));
1078             }
1079             throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
1080         }
1081         return unit.addTo(this, amountToAdd);
1082     }
1083 
1084     //-----------------------------------------------------------------------
1085     /**
1086      * Returns a copy of this {@code LocalDate} with the specified period in years added.
1087      * <p>
1088      * This method adds the specified amount to the years field in three steps:
1089      * <ol>
1090      * <li>Add the input years to the year field</li>
1091      * <li>Check if the resulting date would be invalid</li>
1092      * <li>Adjust the day-of-month to the last valid day if necessary</li>
1093      * </ol>
1094      * <p>
1095      * For example, 2008-02-29 (leap year) plus one year would result in the
1096      * invalid date 2009-02-29 (standard year). Instead of returning an invalid
1097      * result, the last valid day of the month, 2009-02-28, is selected instead.
1098      * <p>
1099      * This instance is immutable and unaffected by this method call.
1100      *
1101      * @param yearsToAdd  the years to add, may be negative
1102      * @return a {@code LocalDate} based on this date with the years added, not null
1103      * @throws DateTimeException if the result exceeds the supported date range
1104      */
plusYears(long yearsToAdd)1105     public LocalDate plusYears(long yearsToAdd) {
1106         if (yearsToAdd == 0) {
1107             return this;
1108         }
1109         int newYear = YEAR.checkValidIntValue(year + yearsToAdd);  // safe overflow
1110         return resolvePreviousValid(newYear, month, day);
1111     }
1112 
1113     /**
1114      * Returns a copy of this {@code LocalDate} with the specified period in months added.
1115      * <p>
1116      * This method adds the specified amount to the months field in three steps:
1117      * <ol>
1118      * <li>Add the input months to the month-of-year field</li>
1119      * <li>Check if the resulting date would be invalid</li>
1120      * <li>Adjust the day-of-month to the last valid day if necessary</li>
1121      * </ol>
1122      * <p>
1123      * For example, 2007-03-31 plus one month would result in the invalid date
1124      * 2007-04-31. Instead of returning an invalid result, the last valid day
1125      * of the month, 2007-04-30, is selected instead.
1126      * <p>
1127      * This instance is immutable and unaffected by this method call.
1128      *
1129      * @param monthsToAdd  the months to add, may be negative
1130      * @return a {@code LocalDate} based on this date with the months added, not null
1131      * @throws DateTimeException if the result exceeds the supported date range
1132      */
plusMonths(long monthsToAdd)1133     public LocalDate plusMonths(long monthsToAdd) {
1134         if (monthsToAdd == 0) {
1135             return this;
1136         }
1137         long monthCount = year * 12L + (month - 1);
1138         long calcMonths = monthCount + monthsToAdd;  // safe overflow
1139         int newYear = YEAR.checkValidIntValue(Jdk8Methods.floorDiv(calcMonths, 12));
1140         int newMonth = Jdk8Methods.floorMod(calcMonths, 12) + 1;
1141         return resolvePreviousValid(newYear, newMonth, day);
1142     }
1143 
1144     /**
1145      * Returns a copy of this {@code LocalDate} with the specified period in weeks added.
1146      * <p>
1147      * This method adds the specified amount in weeks to the days field incrementing
1148      * the month and year fields as necessary to ensure the result remains valid.
1149      * The result is only invalid if the maximum/minimum year is exceeded.
1150      * <p>
1151      * For example, 2008-12-31 plus one week would result in 2009-01-07.
1152      * <p>
1153      * This instance is immutable and unaffected by this method call.
1154      *
1155      * @param weeksToAdd  the weeks to add, may be negative
1156      * @return a {@code LocalDate} based on this date with the weeks added, not null
1157      * @throws DateTimeException if the result exceeds the supported date range
1158      */
plusWeeks(long weeksToAdd)1159     public LocalDate plusWeeks(long weeksToAdd) {
1160         return plusDays(Jdk8Methods.safeMultiply(weeksToAdd, 7));
1161     }
1162 
1163     /**
1164      * Returns a copy of this {@code LocalDate} with the specified number of days added.
1165      * <p>
1166      * This method adds the specified amount to the days field incrementing the
1167      * month and year fields as necessary to ensure the result remains valid.
1168      * The result is only invalid if the maximum/minimum year is exceeded.
1169      * <p>
1170      * For example, 2008-12-31 plus one day would result in 2009-01-01.
1171      * <p>
1172      * This instance is immutable and unaffected by this method call.
1173      *
1174      * @param daysToAdd  the days to add, may be negative
1175      * @return a {@code LocalDate} based on this date with the days added, not null
1176      * @throws DateTimeException if the result exceeds the supported date range
1177      */
plusDays(long daysToAdd)1178     public LocalDate plusDays(long daysToAdd) {
1179         if (daysToAdd == 0) {
1180             return this;
1181         }
1182         long mjDay = Jdk8Methods.safeAdd(toEpochDay(), daysToAdd);
1183         return LocalDate.ofEpochDay(mjDay);
1184     }
1185 
1186     //-----------------------------------------------------------------------
1187     /**
1188      * Returns a copy of this date with the specified period subtracted.
1189      * <p>
1190      * This method returns a new date based on this date with the specified period subtracted.
1191      * The amount is typically {@link Period} but may be any other type implementing
1192      * the {@link TemporalAmount} interface.
1193      * The calculation is delegated to the specified adjuster, which typically calls
1194      * back to {@link #minus(long, TemporalUnit)}.
1195      * <p>
1196      * This instance is immutable and unaffected by this method call.
1197      *
1198      * @param amount  the amount to subtract, not null
1199      * @return a {@code LocalDate} based on this date with the subtraction made, not null
1200      * @throws DateTimeException if the subtraction cannot be made
1201      * @throws ArithmeticException if numeric overflow occurs
1202      */
1203     @Override
minus(TemporalAmount amount)1204     public LocalDate minus(TemporalAmount amount) {
1205         return (LocalDate) amount.subtractFrom(this);
1206     }
1207 
1208     /**
1209      * Returns a copy of this date with the specified period subtracted.
1210      * <p>
1211      * This method returns a new date based on this date with the specified period subtracted.
1212      * This can be used to subtract any period that is defined by a unit, for example to subtract years, months or days.
1213      * The unit is responsible for the details of the calculation, including the resolution
1214      * of any edge cases in the calculation.
1215      * <p>
1216      * This instance is immutable and unaffected by this method call.
1217      *
1218      * @param amountToSubtract  the amount of the unit to subtract from the result, may be negative
1219      * @param unit  the unit of the period to subtract, not null
1220      * @return a {@code LocalDate} based on this date with the specified period subtracted, not null
1221      * @throws DateTimeException if the unit cannot be added to this type
1222      */
1223     @Override
minus(long amountToSubtract, TemporalUnit unit)1224     public LocalDate minus(long amountToSubtract, TemporalUnit unit) {
1225         return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit));
1226     }
1227 
1228     //-----------------------------------------------------------------------
1229     /**
1230      * Returns a copy of this {@code LocalDate} with the specified period in years subtracted.
1231      * <p>
1232      * This method subtracts the specified amount from the years field in three steps:
1233      * <ol>
1234      * <li>Subtract the input years to the year field</li>
1235      * <li>Check if the resulting date would be invalid</li>
1236      * <li>Adjust the day-of-month to the last valid day if necessary</li>
1237      * </ol>
1238      * <p>
1239      * For example, 2008-02-29 (leap year) minus one year would result in the
1240      * invalid date 2007-02-29 (standard year). Instead of returning an invalid
1241      * result, the last valid day of the month, 2007-02-28, is selected instead.
1242      * <p>
1243      * This instance is immutable and unaffected by this method call.
1244      *
1245      * @param yearsToSubtract  the years to subtract, may be negative
1246      * @return a {@code LocalDate} based on this date with the years subtracted, not null
1247      * @throws DateTimeException if the result exceeds the supported date range
1248      */
minusYears(long yearsToSubtract)1249     public LocalDate minusYears(long yearsToSubtract) {
1250         return (yearsToSubtract == Long.MIN_VALUE ? plusYears(Long.MAX_VALUE).plusYears(1) : plusYears(-yearsToSubtract));
1251     }
1252 
1253     /**
1254      * Returns a copy of this {@code LocalDate} with the specified period in months subtracted.
1255      * <p>
1256      * This method subtracts the specified amount from the months field in three steps:
1257      * <ol>
1258      * <li>Subtract the input months to the month-of-year field</li>
1259      * <li>Check if the resulting date would be invalid</li>
1260      * <li>Adjust the day-of-month to the last valid day if necessary</li>
1261      * </ol>
1262      * <p>
1263      * For example, 2007-03-31 minus one month would result in the invalid date
1264      * 2007-02-31. Instead of returning an invalid result, the last valid day
1265      * of the month, 2007-02-28, is selected instead.
1266      * <p>
1267      * This instance is immutable and unaffected by this method call.
1268      *
1269      * @param monthsToSubtract  the months to subtract, may be negative
1270      * @return a {@code LocalDate} based on this date with the months subtracted, not null
1271      * @throws DateTimeException if the result exceeds the supported date range
1272      */
minusMonths(long monthsToSubtract)1273     public LocalDate minusMonths(long monthsToSubtract) {
1274         return (monthsToSubtract == Long.MIN_VALUE ? plusMonths(Long.MAX_VALUE).plusMonths(1) : plusMonths(-monthsToSubtract));
1275     }
1276 
1277     /**
1278      * Returns a copy of this {@code LocalDate} with the specified period in weeks subtracted.
1279      * <p>
1280      * This method subtracts the specified amount in weeks from the days field decrementing
1281      * the month and year fields as necessary to ensure the result remains valid.
1282      * The result is only invalid if the maximum/minimum year is exceeded.
1283      * <p>
1284      * For example, 2009-01-07 minus one week would result in 2008-12-31.
1285      * <p>
1286      * This instance is immutable and unaffected by this method call.
1287      *
1288      * @param weeksToSubtract  the weeks to subtract, may be negative
1289      * @return a {@code LocalDate} based on this date with the weeks subtracted, not null
1290      * @throws DateTimeException if the result exceeds the supported date range
1291      */
minusWeeks(long weeksToSubtract)1292     public LocalDate minusWeeks(long weeksToSubtract) {
1293         return (weeksToSubtract == Long.MIN_VALUE ? plusWeeks(Long.MAX_VALUE).plusWeeks(1) : plusWeeks(-weeksToSubtract));
1294     }
1295 
1296     /**
1297      * Returns a copy of this {@code LocalDate} with the specified number of days subtracted.
1298      * <p>
1299      * This method subtracts the specified amount from the days field decrementing the
1300      * month and year fields as necessary to ensure the result remains valid.
1301      * The result is only invalid if the maximum/minimum year is exceeded.
1302      * <p>
1303      * For example, 2009-01-01 minus one day would result in 2008-12-31.
1304      * <p>
1305      * This instance is immutable and unaffected by this method call.
1306      *
1307      * @param daysToSubtract  the days to subtract, may be negative
1308      * @return a {@code LocalDate} based on this date with the days subtracted, not null
1309      * @throws DateTimeException if the result exceeds the supported date range
1310      */
minusDays(long daysToSubtract)1311     public LocalDate minusDays(long daysToSubtract) {
1312         return (daysToSubtract == Long.MIN_VALUE ? plusDays(Long.MAX_VALUE).plusDays(1) : plusDays(-daysToSubtract));
1313     }
1314 
1315     //-----------------------------------------------------------------------
1316     /**
1317      * Queries this date using the specified query.
1318      * <p>
1319      * This queries this date using the specified query strategy object.
1320      * The {@code TemporalQuery} object defines the logic to be used to
1321      * obtain the result. Read the documentation of the query to understand
1322      * what the result of this method will be.
1323      * <p>
1324      * The result of this method is obtained by invoking the
1325      * {@link TemporalQuery#queryFrom(TemporalAccessor)} method on the
1326      * specified query passing {@code this} as the argument.
1327      *
1328      * @param <R> the type of the result
1329      * @param query  the query to invoke, not null
1330      * @return the query result, null may be returned (defined by the query)
1331      * @throws DateTimeException if unable to query (defined by the query)
1332      * @throws ArithmeticException if numeric overflow occurs (defined by the query)
1333      */
1334     @SuppressWarnings("unchecked")
1335     @Override
query(TemporalQuery<R> query)1336     public <R> R query(TemporalQuery<R> query) {
1337         if (query == TemporalQueries.localDate()) {
1338             return (R) this;
1339         }
1340         return super.query(query);
1341     }
1342 
1343     /**
1344      * Adjusts the specified temporal object to have the same date as this object.
1345      * <p>
1346      * This returns a temporal object of the same observable type as the input
1347      * with the date changed to be the same as this.
1348      * <p>
1349      * The adjustment is equivalent to using {@link Temporal#with(TemporalField, long)}
1350      * passing {@link ChronoField#EPOCH_DAY} as the field.
1351      * <p>
1352      * In most cases, it is clearer to reverse the calling pattern by using
1353      * {@link Temporal#with(TemporalAdjuster)}:
1354      * <pre>
1355      *   // these two lines are equivalent, but the second approach is recommended
1356      *   temporal = thisLocalDate.adjustInto(temporal);
1357      *   temporal = temporal.with(thisLocalDate);
1358      * </pre>
1359      * <p>
1360      * This instance is immutable and unaffected by this method call.
1361      *
1362      * @param temporal  the target object to be adjusted, not null
1363      * @return the adjusted object, not null
1364      * @throws DateTimeException if unable to make the adjustment
1365      * @throws ArithmeticException if numeric overflow occurs
1366      */
1367     @Override  // override for Javadoc
adjustInto(Temporal temporal)1368     public Temporal adjustInto(Temporal temporal) {
1369         return super.adjustInto(temporal);
1370     }
1371 
1372     /**
1373      * Calculates the period between this date and another date in
1374      * terms of the specified unit.
1375      * <p>
1376      * This calculates the period between two dates in terms of a single unit.
1377      * The start and end points are {@code this} and the specified date.
1378      * The result will be negative if the end is before the start.
1379      * The {@code Temporal} passed to this method must be a {@code LocalDate}.
1380      * For example, the period in days between two dates can be calculated
1381      * using {@code startDate.until(endDate, DAYS)}.
1382      * <p>
1383      * The calculation returns a whole number, representing the number of
1384      * complete units between the two dates.
1385      * For example, the period in months between 2012-06-15 and 2012-08-14
1386      * will only be one month as it is one day short of two months.
1387      * <p>
1388      * This method operates in association with {@link TemporalUnit#between}.
1389      * The result of this method is a {@code long} representing the amount of
1390      * the specified unit. By contrast, the result of {@code between} is an
1391      * object that can be used directly in addition/subtraction:
1392      * <pre>
1393      *   long period = start.until(end, MONTHS);   // this method
1394      *   dateTime.plus(MONTHS.between(start, end));      // use in plus/minus
1395      * </pre>
1396      * <p>
1397      * The calculation is implemented in this method for {@link ChronoUnit}.
1398      * The units {@code DAYS}, {@code WEEKS}, {@code MONTHS}, {@code YEARS},
1399      * {@code DECADES}, {@code CENTURIES}, {@code MILLENNIA} and {@code ERAS}
1400      * are supported. Other {@code ChronoUnit} values will throw an exception.
1401      * <p>
1402      * If the unit is not a {@code ChronoUnit}, then the result of this method
1403      * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)}
1404      * passing {@code this} as the first argument and the input temporal as
1405      * the second argument.
1406      * <p>
1407      * This instance is immutable and unaffected by this method call.
1408      *
1409      * @param endExclusive  the end date, which is converted to a {@code LocalDate}, not null
1410      * @param unit  the unit to measure the period in, not null
1411      * @return the amount of the period between this date and the end date
1412      * @throws DateTimeException if the period cannot be calculated
1413      * @throws ArithmeticException if numeric overflow occurs
1414      */
1415     @Override
until(Temporal endExclusive, TemporalUnit unit)1416     public long until(Temporal endExclusive, TemporalUnit unit) {
1417         LocalDate end = LocalDate.from(endExclusive);
1418         if (unit instanceof ChronoUnit) {
1419             switch ((ChronoUnit) unit) {
1420                 case DAYS: return daysUntil(end);
1421                 case WEEKS: return daysUntil(end) / 7;
1422                 case MONTHS: return monthsUntil(end);
1423                 case YEARS: return monthsUntil(end) / 12;
1424                 case DECADES: return monthsUntil(end) / 120;
1425                 case CENTURIES: return monthsUntil(end) / 1200;
1426                 case MILLENNIA: return monthsUntil(end) / 12000;
1427                 case ERAS: return end.getLong(ERA) - getLong(ERA);
1428             }
1429             throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
1430         }
1431         return unit.between(this, end);
1432     }
1433 
daysUntil(LocalDate end)1434     long daysUntil(LocalDate end) {
1435         return end.toEpochDay() - toEpochDay();  // no overflow
1436     }
1437 
monthsUntil(LocalDate end)1438     private long monthsUntil(LocalDate end) {
1439         long packed1 = getProlepticMonth() * 32L + getDayOfMonth();  // no overflow
1440         long packed2 = end.getProlepticMonth() * 32L + end.getDayOfMonth();  // no overflow
1441         return (packed2 - packed1) / 32;
1442     }
1443 
1444     /**
1445      * Calculates the period between this date and another date as a {@code Period}.
1446      * <p>
1447      * This calculates the period between two dates in terms of years, months and days.
1448      * The start and end points are {@code this} and the specified date.
1449      * The result will be negative if the end is before the start.
1450      * <p>
1451      * The calculation is performed using the ISO calendar system.
1452      * If necessary, the input date will be converted to ISO.
1453      * <p>
1454      * The start date is included, but the end date is not.
1455      * The period is calculated by removing complete months, then calculating
1456      * the remaining number of days, adjusting to ensure that both have the same sign.
1457      * The number of months is then normalized into years and months based on a 12 month year.
1458      * A month is considered to be complete if the end day-of-month is greater
1459      * than or equal to the start day-of-month.
1460      * For example, from {@code 2010-01-15} to {@code 2011-03-18} is "1 year, 2 months and 3 days".
1461      * <p>
1462      * The result of this method can be a negative period if the end is before the start.
1463      * The negative sign will be the same in each of year, month and day.
1464      * <p>
1465      * There are two equivalent ways of using this method.
1466      * The first is to invoke this method.
1467      * The second is to use {@link Period#between(LocalDate, LocalDate)}:
1468      * <pre>
1469      *   // these two lines are equivalent
1470      *   period = start.until(end);
1471      *   period = Period.between(start, end);
1472      * </pre>
1473      * The choice should be made based on which makes the code more readable.
1474      *
1475      * @param endDate  the end date, exclusive, which may be in any chronology, not null
1476      * @return the period between this date and the end date, not null
1477      */
1478     @Override
until(ChronoLocalDate endDate)1479     public Period until(ChronoLocalDate endDate) {
1480         LocalDate end = LocalDate.from(endDate);
1481         long totalMonths = end.getProlepticMonth() - this.getProlepticMonth();  // safe
1482         int days = end.day - this.day;
1483         if (totalMonths > 0 && days < 0) {
1484             totalMonths--;
1485             LocalDate calcDate = this.plusMonths(totalMonths);
1486             days = (int) (end.toEpochDay() - calcDate.toEpochDay());  // safe
1487         } else if (totalMonths < 0 && days > 0) {
1488             totalMonths++;
1489             days -= end.lengthOfMonth();
1490         }
1491         long years = totalMonths / 12;  // safe
1492         int months = (int) (totalMonths % 12);  // safe
1493         return Period.of(Jdk8Methods.safeToInt(years), months, days);
1494     }
1495 
1496     //-----------------------------------------------------------------------
1497     /**
1498      * Combines this date with a time to create a {@code LocalDateTime}.
1499      * <p>
1500      * This returns a {@code LocalDateTime} formed from this date at the specified time.
1501      * All possible combinations of date and time are valid.
1502      *
1503      * @param time  the time to combine with, not null
1504      * @return the local date-time formed from this date and the specified time, not null
1505      */
1506     @Override
atTime(LocalTime time)1507     public LocalDateTime atTime(LocalTime time) {
1508         return LocalDateTime.of(this, time);
1509     }
1510 
1511     /**
1512      * Combines this date with a time to create a {@code LocalDateTime}.
1513      * <p>
1514      * This returns a {@code LocalDateTime} formed from this date at the
1515      * specified hour and minute.
1516      * The seconds and nanosecond fields will be set to zero.
1517      * The individual time fields must be within their valid range.
1518      * All possible combinations of date and time are valid.
1519      *
1520      * @param hour  the hour-of-day to use, from 0 to 23
1521      * @param minute  the minute-of-hour to use, from 0 to 59
1522      * @return the local date-time formed from this date and the specified time, not null
1523      * @throws DateTimeException if the value of any field is out of range
1524      */
atTime(int hour, int minute)1525     public LocalDateTime atTime(int hour, int minute) {
1526         return atTime(LocalTime.of(hour, minute));
1527     }
1528 
1529     /**
1530      * Combines this date with a time to create a {@code LocalDateTime}.
1531      * <p>
1532      * This returns a {@code LocalDateTime} formed from this date at the
1533      * specified hour, minute and second.
1534      * The nanosecond field will be set to zero.
1535      * The individual time fields must be within their valid range.
1536      * All possible combinations of date and time are valid.
1537      *
1538      * @param hour  the hour-of-day to use, from 0 to 23
1539      * @param minute  the minute-of-hour to use, from 0 to 59
1540      * @param second  the second-of-minute to represent, from 0 to 59
1541      * @return the local date-time formed from this date and the specified time, not null
1542      * @throws DateTimeException if the value of any field is out of range
1543      */
atTime(int hour, int minute, int second)1544     public LocalDateTime atTime(int hour, int minute, int second) {
1545         return atTime(LocalTime.of(hour, minute, second));
1546     }
1547 
1548     /**
1549      * Combines this date with a time to create a {@code LocalDateTime}.
1550      * <p>
1551      * This returns a {@code LocalDateTime} formed from this date at the
1552      * specified hour, minute, second and nanosecond.
1553      * The individual time fields must be within their valid range.
1554      * All possible combinations of date and time are valid.
1555      *
1556      * @param hour  the hour-of-day to use, from 0 to 23
1557      * @param minute  the minute-of-hour to use, from 0 to 59
1558      * @param second  the second-of-minute to represent, from 0 to 59
1559      * @param nanoOfSecond  the nano-of-second to represent, from 0 to 999,999,999
1560      * @return the local date-time formed from this date and the specified time, not null
1561      * @throws DateTimeException if the value of any field is out of range
1562      */
atTime(int hour, int minute, int second, int nanoOfSecond)1563     public LocalDateTime atTime(int hour, int minute, int second, int nanoOfSecond) {
1564         return atTime(LocalTime.of(hour, minute, second, nanoOfSecond));
1565     }
1566 
1567     /**
1568      * Combines this date with an offset time to create an {@code OffsetDateTime}.
1569      * <p>
1570      * This returns an {@code OffsetDateTime} formed from this date at the specified time.
1571      * All possible combinations of date and time are valid.
1572      *
1573      * @param time  the time to combine with, not null
1574      * @return the offset date-time formed from this date and the specified time, not null
1575      */
atTime(OffsetTime time)1576     public OffsetDateTime atTime(OffsetTime time) {
1577         return OffsetDateTime.of(LocalDateTime.of(this, time.toLocalTime()), time.getOffset());
1578     }
1579 
1580     /**
1581      * Combines this date with the time of midnight to create a {@code LocalDateTime}
1582      * at the start of this date.
1583      * <p>
1584      * This returns a {@code LocalDateTime} formed from this date at the time of
1585      * midnight, 00:00, at the start of this date.
1586      *
1587      * @return the local date-time of midnight at the start of this date, not null
1588      */
atStartOfDay()1589     public LocalDateTime atStartOfDay() {
1590         return LocalDateTime.of(this, LocalTime.MIDNIGHT);
1591     }
1592 
1593     /**
1594      * Combines this date with a time-zone to create a {@code ZonedDateTime}
1595      * at the start of the day
1596      * <p>
1597      * This returns a {@code ZonedDateTime} formed from this date at the
1598      * specified zone, with the time set to be the earliest valid time according
1599      * to the rules in the time-zone.
1600      * <p>
1601      * Time-zone rules, such as daylight savings, mean that not every local date-time
1602      * is valid for the specified zone, thus the local date-time may not be midnight.
1603      * <p>
1604      * In most cases, there is only one valid offset for a local date-time.
1605      * In the case of an overlap, there are two valid offsets, and the earlier one is used,
1606      * corresponding to the first occurrence of midnight on the date.
1607      * In the case of a gap, the zoned date-time will represent the instant just after the gap.
1608      * <p>
1609      * If the zone ID is a {@link ZoneOffset}, then the result always has a time of midnight.
1610      * <p>
1611      * To convert to a specific time in a given time-zone call {@link #atTime(LocalTime)}
1612      * followed by {@link LocalDateTime#atZone(ZoneId)}.
1613      *
1614      * @param zone  the zone ID to use, not null
1615      * @return the zoned date-time formed from this date and the earliest valid time for the zone, not null
1616      */
atStartOfDay(ZoneId zone)1617     public ZonedDateTime atStartOfDay(ZoneId zone) {
1618         Jdk8Methods.requireNonNull(zone, "zone");
1619         // need to handle case where there is a gap from 11:30 to 00:30
1620         // standard ZDT factory would result in 01:00 rather than 00:30
1621         LocalDateTime ldt = atTime(LocalTime.MIDNIGHT);
1622         if (zone instanceof ZoneOffset == false) {
1623             ZoneRules rules = zone.getRules();
1624             ZoneOffsetTransition trans = rules.getTransition(ldt);
1625             if (trans != null && trans.isGap()) {
1626                 ldt = trans.getDateTimeAfter();
1627             }
1628         }
1629         return ZonedDateTime.of(ldt, zone);
1630     }
1631 
1632     //-----------------------------------------------------------------------
1633     @Override
toEpochDay()1634     public long toEpochDay() {
1635         long y = year;
1636         long m = month;
1637         long total = 0;
1638         total += 365 * y;
1639         if (y >= 0) {
1640             total += (y + 3) / 4 - (y + 99) / 100 + (y + 399) / 400;
1641         } else {
1642             total -= y / -4 - y / -100 + y / -400;
1643         }
1644         total += ((367 * m - 362) / 12);
1645         total += day - 1;
1646         if (m > 2) {
1647             total--;
1648             if (isLeapYear() == false) {
1649                 total--;
1650             }
1651         }
1652         return total - DAYS_0000_TO_1970;
1653     }
1654 
1655     //-----------------------------------------------------------------------
1656     /**
1657      * Compares this date to another date.
1658      * <p>
1659      * The comparison is primarily based on the date, from earliest to latest.
1660      * It is "consistent with equals", as defined by {@link Comparable}.
1661      * <p>
1662      * If all the dates being compared are instances of {@code LocalDate},
1663      * then the comparison will be entirely based on the date.
1664      * If some dates being compared are in different chronologies, then the
1665      * chronology is also considered, see {@link ChronoLocalDate#compareTo}.
1666      *
1667      * @param other  the other date to compare to, not null
1668      * @return the comparator value, negative if less, positive if greater
1669      */
1670     @Override  // override for Javadoc and performance
compareTo(ChronoLocalDate other)1671     public int compareTo(ChronoLocalDate other) {
1672         if (other instanceof LocalDate) {
1673             return compareTo0((LocalDate) other);
1674         }
1675         return super.compareTo(other);
1676     }
1677 
compareTo0(LocalDate otherDate)1678     int compareTo0(LocalDate otherDate) {
1679         int cmp = (year - otherDate.year);
1680         if (cmp == 0) {
1681             cmp = (month - otherDate.month);
1682             if (cmp == 0) {
1683                 cmp = (day - otherDate.day);
1684             }
1685         }
1686         return cmp;
1687     }
1688 
1689     /**
1690      * Checks if this date is after the specified date.
1691      * <p>
1692      * This checks to see if this date represents a point on the
1693      * local time-line after the other date.
1694      * <pre>
1695      *   LocalDate a = LocalDate.of(2012, 6, 30);
1696      *   LocalDate b = LocalDate.of(2012, 7, 1);
1697      *   a.isAfter(b) == false
1698      *   a.isAfter(a) == false
1699      *   b.isAfter(a) == true
1700      * </pre>
1701      * <p>
1702      * This method only considers the position of the two dates on the local time-line.
1703      * It does not take into account the chronology, or calendar system.
1704      * This is different from the comparison in {@link #compareTo(ChronoLocalDate)},
1705      * but is the same approach as {@link #DATE_COMPARATOR}.
1706      *
1707      * @param other  the other date to compare to, not null
1708      * @return true if this date is after the specified date
1709      */
1710     @Override  // override for Javadoc and performance
isAfter(ChronoLocalDate other)1711     public boolean isAfter(ChronoLocalDate other) {
1712         if (other instanceof LocalDate) {
1713             return compareTo0((LocalDate) other) > 0;
1714         }
1715         return super.isAfter(other);
1716     }
1717 
1718     /**
1719      * Checks if this date is before the specified date.
1720      * <p>
1721      * This checks to see if this date represents a point on the
1722      * local time-line before the other date.
1723      * <pre>
1724      *   LocalDate a = LocalDate.of(2012, 6, 30);
1725      *   LocalDate b = LocalDate.of(2012, 7, 1);
1726      *   a.isBefore(b) == true
1727      *   a.isBefore(a) == false
1728      *   b.isBefore(a) == false
1729      * </pre>
1730      * <p>
1731      * This method only considers the position of the two dates on the local time-line.
1732      * It does not take into account the chronology, or calendar system.
1733      * This is different from the comparison in {@link #compareTo(ChronoLocalDate)},
1734      * but is the same approach as {@link #DATE_COMPARATOR}.
1735      *
1736      * @param other  the other date to compare to, not null
1737      * @return true if this date is before the specified date
1738      */
1739     @Override  // override for Javadoc and performance
isBefore(ChronoLocalDate other)1740     public boolean isBefore(ChronoLocalDate other) {
1741         if (other instanceof LocalDate) {
1742             return compareTo0((LocalDate) other) < 0;
1743         }
1744         return super.isBefore(other);
1745     }
1746 
1747     /**
1748      * Checks if this date is equal to the specified date.
1749      * <p>
1750      * This checks to see if this date represents the same point on the
1751      * local time-line as the other date.
1752      * <pre>
1753      *   LocalDate a = LocalDate.of(2012, 6, 30);
1754      *   LocalDate b = LocalDate.of(2012, 7, 1);
1755      *   a.isEqual(b) == false
1756      *   a.isEqual(a) == true
1757      *   b.isEqual(a) == false
1758      * </pre>
1759      * <p>
1760      * This method only considers the position of the two dates on the local time-line.
1761      * It does not take into account the chronology, or calendar system.
1762      * This is different from the comparison in {@link #compareTo(ChronoLocalDate)}
1763      * but is the same approach as {@link #DATE_COMPARATOR}.
1764      *
1765      * @param other  the other date to compare to, not null
1766      * @return true if this date is equal to the specified date
1767      */
1768     @Override  // override for Javadoc and performance
isEqual(ChronoLocalDate other)1769     public boolean isEqual(ChronoLocalDate other) {
1770         if (other instanceof LocalDate) {
1771             return compareTo0((LocalDate) other) == 0;
1772         }
1773         return super.isEqual(other);
1774     }
1775 
1776     //-----------------------------------------------------------------------
1777     /**
1778      * Checks if this date is equal to another date.
1779      * <p>
1780      * Compares this {@code LocalDate} with another ensuring that the date is the same.
1781      * <p>
1782      * Only objects of type {@code LocalDate} are compared, other types return false.
1783      * To compare the dates of two {@code TemporalAccessor} instances, including dates
1784      * in two different chronologies, use {@link ChronoField#EPOCH_DAY} as a comparator.
1785      *
1786      * @param obj  the object to check, null returns false
1787      * @return true if this is equal to the other date
1788      */
1789     @Override
equals(Object obj)1790     public boolean equals(Object obj) {
1791         if (this == obj) {
1792             return true;
1793         }
1794         if (obj instanceof LocalDate) {
1795             return compareTo0((LocalDate) obj) == 0;
1796         }
1797         return false;
1798     }
1799 
1800     /**
1801      * A hash code for this date.
1802      *
1803      * @return a suitable hash code
1804      */
1805     @Override
hashCode()1806     public int hashCode() {
1807         int yearValue = year;
1808         int monthValue = month;
1809         int dayValue = day;
1810         return (yearValue & 0xFFFFF800) ^ ((yearValue << 11) + (monthValue << 6) + (dayValue));
1811     }
1812 
1813     //-----------------------------------------------------------------------
1814     /**
1815      * Outputs this date as a {@code String}, such as {@code 2007-12-23}.
1816      * <p>
1817      * The output will be in the ISO-8601 format {@code yyyy-MM-dd}.
1818      *
1819      * @return a string representation of this date, not null
1820      */
1821     @Override
toString()1822     public String toString() {
1823         int yearValue = year;
1824         int monthValue = month;
1825         int dayValue = day;
1826         int absYear = Math.abs(yearValue);
1827         StringBuilder buf = new StringBuilder(10);
1828         if (absYear < 1000) {
1829             if (yearValue < 0) {
1830                 buf.append(yearValue - 10000).deleteCharAt(1);
1831             } else {
1832                 buf.append(yearValue + 10000).deleteCharAt(0);
1833             }
1834         } else {
1835             if (yearValue > 9999) {
1836                 buf.append('+');
1837             }
1838             buf.append(yearValue);
1839         }
1840         return buf.append(monthValue < 10 ? "-0" : "-")
1841             .append(monthValue)
1842             .append(dayValue < 10 ? "-0" : "-")
1843             .append(dayValue)
1844             .toString();
1845     }
1846 
1847     /**
1848      * Outputs this date as a {@code String} using the formatter.
1849      * <p>
1850      * This date will be passed to the formatter
1851      * {@link DateTimeFormatter#format(TemporalAccessor) print method}.
1852      *
1853      * @param formatter  the formatter to use, not null
1854      * @return the formatted date string, not null
1855      * @throws DateTimeException if an error occurs during printing
1856      */
1857     @Override  // override for Javadoc
format(DateTimeFormatter formatter)1858     public String format(DateTimeFormatter formatter) {
1859         return super.format(formatter);
1860     }
1861 
1862     //-----------------------------------------------------------------------
writeReplace()1863     private Object writeReplace() {
1864         return new Ser(Ser.LOCAL_DATE_TYPE, this);
1865     }
1866 
1867     /**
1868      * Defend against malicious streams.
1869      * @return never
1870      * @throws InvalidObjectException always
1871      */
readResolve()1872     private Object readResolve() throws ObjectStreamException {
1873         throw new InvalidObjectException("Deserialization via serialization delegate");
1874     }
1875 
writeExternal(DataOutput out)1876     void writeExternal(DataOutput out) throws IOException {
1877         out.writeInt(year);
1878         out.writeByte(month);
1879         out.writeByte(day);
1880     }
1881 
readExternal(DataInput in)1882     static LocalDate readExternal(DataInput in) throws IOException {
1883         int year = in.readInt();
1884         int month = in.readByte();
1885         int dayOfMonth = in.readByte();
1886         return LocalDate.of(year, month, dayOfMonth);
1887     }
1888 
1889 }
1890