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