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