001    /*
002     *  Copyright 2001-2013 Stephen Colebourne
003     *
004     *  Licensed under the Apache License, Version 2.0 (the "License");
005     *  you may not use this file except in compliance with the License.
006     *  You may obtain a copy of the License at
007     *
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     *
010     *  Unless required by applicable law or agreed to in writing, software
011     *  distributed under the License is distributed on an "AS IS" BASIS,
012     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     *  See the License for the specific language governing permissions and
014     *  limitations under the License.
015     */
016    package org.joda.time;
017    
018    import java.io.IOException;
019    import java.io.ObjectInputStream;
020    import java.io.ObjectOutputStream;
021    import java.io.Serializable;
022    import java.util.Calendar;
023    import java.util.Date;
024    import java.util.GregorianCalendar;
025    import java.util.HashSet;
026    import java.util.Locale;
027    import java.util.Set;
028    import java.util.TimeZone;
029    
030    import org.joda.convert.FromString;
031    import org.joda.convert.ToString;
032    import org.joda.time.base.BaseLocal;
033    import org.joda.time.chrono.ISOChronology;
034    import org.joda.time.convert.ConverterManager;
035    import org.joda.time.convert.PartialConverter;
036    import org.joda.time.field.AbstractReadableInstantFieldProperty;
037    import org.joda.time.field.FieldUtils;
038    import org.joda.time.format.DateTimeFormat;
039    import org.joda.time.format.DateTimeFormatter;
040    import org.joda.time.format.ISODateTimeFormat;
041    
042    /**
043     * LocalDate is an immutable datetime class representing a date
044     * without a time zone.
045     * <p>
046     * LocalDate implements the {@link ReadablePartial} interface.
047     * To do this, the interface methods focus on the key fields -
048     * Year, MonthOfYear and DayOfMonth.
049     * However, <b>all</b> date fields may in fact be queried.
050     * <p>
051     * LocalDate differs from DateMidnight in that this class does not
052     * have a time zone and does not represent a single instant in time.
053     * <p>
054     * Calculations on LocalDate are performed using a {@link Chronology}.
055     * This chronology will be set internally to be in the UTC time zone
056     * for all calculations.
057     *
058     * <p>Each individual field can be queried in two ways:
059     * <ul>
060     * <li><code>getMonthOfYear()</code>
061     * <li><code>monthOfYear().get()</code>
062     * </ul>
063     * The second technique also provides access to other useful methods on the
064     * field:
065     * <ul>
066     * <li>numeric value
067     * <li>text value
068     * <li>short text value
069     * <li>maximum/minimum values
070     * <li>add/subtract
071     * <li>set
072     * <li>rounding
073     * </ul>
074     *
075     * <p>
076     * LocalDate is thread-safe and immutable, provided that the Chronology is as well.
077     * All standard Chronology classes supplied are thread-safe and immutable.
078     *
079     * @author Stephen Colebourne
080     * @since 1.3
081     */
082    public final class LocalDate
083            extends BaseLocal
084            implements ReadablePartial, Serializable {
085    
086        /** Serialization lock */
087        private static final long serialVersionUID = -8775358157899L;
088    
089        /** The index of the year field in the field array */
090        private static final int YEAR = 0;
091        /** The index of the monthOfYear field in the field array */
092        private static final int MONTH_OF_YEAR = 1;
093        /** The index of the dayOfMonth field in the field array */
094        private static final int DAY_OF_MONTH = 2;
095        /** Set of known duration types. */
096        private static final Set<DurationFieldType> DATE_DURATION_TYPES = new HashSet<DurationFieldType>();
097        static {
098            DATE_DURATION_TYPES.add(DurationFieldType.days());
099            DATE_DURATION_TYPES.add(DurationFieldType.weeks());
100            DATE_DURATION_TYPES.add(DurationFieldType.months());
101            DATE_DURATION_TYPES.add(DurationFieldType.weekyears());
102            DATE_DURATION_TYPES.add(DurationFieldType.years());
103            DATE_DURATION_TYPES.add(DurationFieldType.centuries());
104            // eras are supported, although the DurationField generally isn't
105            DATE_DURATION_TYPES.add(DurationFieldType.eras());
106        }
107    
108        /** The local millis from 1970-01-01T00:00:00 */
109        private final long iLocalMillis;
110        /** The chronology to use in UTC. */
111        private final Chronology iChronology;
112        /** The cached hash code. */
113        private transient volatile int iHash;
114    
115        //-----------------------------------------------------------------------
116        /**
117         * Obtains a {@code LocalDate} set to the current system millisecond time
118         * using <code>ISOChronology</code> in the default time zone.
119         * 
120         * @return the current date-time, not null
121         * @since 2.0
122         */
123        public static LocalDate now() {
124            return new LocalDate();
125        }
126    
127        /**
128         * Obtains a {@code LocalDate} set to the current system millisecond time
129         * using <code>ISOChronology</code> in the specified time zone.
130         *
131         * @param zone  the time zone, not null
132         * @return the current date-time, not null
133         * @since 2.0
134         */
135        public static LocalDate now(DateTimeZone zone) {
136            if (zone == null) {
137                throw new NullPointerException("Zone must not be null");
138            }
139            return new LocalDate(zone);
140        }
141    
142        /**
143         * Obtains a {@code LocalDate} set to the current system millisecond time
144         * using the specified chronology.
145         *
146         * @param chronology  the chronology, not null
147         * @return the current date-time, not null
148         * @since 2.0
149         */
150        public static LocalDate now(Chronology chronology) {
151            if (chronology == null) {
152                throw new NullPointerException("Chronology must not be null");
153            }
154            return new LocalDate(chronology);
155        }
156    
157        //-----------------------------------------------------------------------
158        /**
159         * Parses a {@code LocalDate} from the specified string.
160         * <p>
161         * This uses {@link ISODateTimeFormat#localDateParser()}.
162         * 
163         * @param str  the string to parse, not null
164         * @since 2.0
165         */
166        @FromString
167        public static LocalDate parse(String str) {
168            return parse(str, ISODateTimeFormat.localDateParser());
169        }
170    
171        /**
172         * Parses a {@code LocalDate} from the specified string using a formatter.
173         * 
174         * @param str  the string to parse, not null
175         * @param formatter  the formatter to use, not null
176         * @since 2.0
177         */
178        public static LocalDate parse(String str, DateTimeFormatter formatter) {
179            return formatter.parseLocalDate(str);
180        }
181    
182        //-----------------------------------------------------------------------
183        /**
184         * Constructs a LocalDate from a <code>java.util.Calendar</code>
185         * using exactly the same field values.
186         * <p>
187         * Each field is queried from the Calendar and assigned to the LocalDate.
188         * This is useful if you have been using the Calendar as a local date,
189         * ignoring the zone.
190         * <p>
191         * One advantage of this method is that this method is unaffected if the
192         * version of the time zone data differs between the JDK and Joda-Time.
193         * That is because the local field values are transferred, calculated using
194         * the JDK time zone data and without using the Joda-Time time zone data.
195         * <p>
196         * This factory method ignores the type of the calendar and always
197         * creates a LocalDate with ISO chronology. It is expected that you
198         * will only pass in instances of <code>GregorianCalendar</code> however
199         * this is not validated.
200         *
201         * @param calendar  the Calendar to extract fields from, not null
202         * @return the created local date, not null
203         * @throws IllegalArgumentException if the calendar is null
204         * @throws IllegalArgumentException if the date is invalid for the ISO chronology
205         */
206        public static LocalDate fromCalendarFields(Calendar calendar) {
207            if (calendar == null) {
208                throw new IllegalArgumentException("The calendar must not be null");
209            }
210            int era = calendar.get(Calendar.ERA);
211            int yearOfEra = calendar.get(Calendar.YEAR);
212            return new LocalDate(
213                (era == GregorianCalendar.AD ? yearOfEra : 1 - yearOfEra),
214                calendar.get(Calendar.MONTH) + 1,
215                calendar.get(Calendar.DAY_OF_MONTH)
216            );
217        }
218    
219        /**
220         * Constructs a LocalDate from a <code>java.util.Date</code>
221         * using exactly the same field values.
222         * <p>
223         * Each field is queried from the Date and assigned to the LocalDate.
224         * This is useful if you have been using the Date as a local date,
225         * ignoring the zone.
226         * <p>
227         * One advantage of this method is that this method is unaffected if the
228         * version of the time zone data differs between the JDK and Joda-Time.
229         * That is because the local field values are transferred, calculated using
230         * the JDK time zone data and without using the Joda-Time time zone data.
231         * <p>
232         * This factory method always creates a LocalDate with ISO chronology.
233         *
234         * @param date  the Date to extract fields from, not null
235         * @return the created local date, not null
236         * @throws IllegalArgumentException if the calendar is null
237         * @throws IllegalArgumentException if the date is invalid for the ISO chronology
238         */
239        @SuppressWarnings("deprecation")
240        public static LocalDate fromDateFields(Date date) {
241            if (date == null) {
242                throw new IllegalArgumentException("The date must not be null");
243            }
244            if (date.getTime() < 0) {
245                // handle years in era BC
246                GregorianCalendar cal = new GregorianCalendar();
247                cal.setTime(date);
248                return fromCalendarFields(cal);
249            }
250            return new LocalDate(
251                date.getYear() + 1900,
252                date.getMonth() + 1,
253                date.getDate()
254            );
255        }
256    
257        //-----------------------------------------------------------------------
258        /**
259         * Constructs an instance set to the current local time evaluated using
260         * ISO chronology in the default zone.
261         * <p>
262         * Once the constructor is completed, the zone is no longer used.
263         * 
264         * @see #now()
265         */
266        public LocalDate() {
267            this(DateTimeUtils.currentTimeMillis(), ISOChronology.getInstance());
268        }
269    
270        /**
271         * Constructs an instance set to the current local time evaluated using
272         * ISO chronology in the specified zone.
273         * <p>
274         * If the specified time zone is null, the default zone is used.
275         * Once the constructor is completed, the zone is no longer used.
276         *
277         * @param zone  the time zone, null means default zone
278         * @see #now(DateTimeZone)
279         */
280        public LocalDate(DateTimeZone zone) {
281            this(DateTimeUtils.currentTimeMillis(), ISOChronology.getInstance(zone));
282        }
283    
284        /**
285         * Constructs an instance set to the current local time evaluated using
286         * specified chronology.
287         * <p>
288         * If the chronology is null, ISO chronology in the default time zone is used.
289         * Once the constructor is completed, the zone is no longer used.
290         *
291         * @param chronology  the chronology, null means ISOChronology in default zone
292         * @see #now(Chronology)
293         */
294        public LocalDate(Chronology chronology) {
295            this(DateTimeUtils.currentTimeMillis(), chronology);
296        }
297    
298        //-----------------------------------------------------------------------
299        /**
300         * Constructs an instance set to the local time defined by the specified
301         * instant evaluated using ISO chronology in the default zone.
302         * <p>
303         * Once the constructor is completed, the zone is no longer used.
304         *
305         * @param instant  the milliseconds from 1970-01-01T00:00:00Z
306         */
307        public LocalDate(long instant) {
308            this(instant, ISOChronology.getInstance());
309        }
310    
311        /**
312         * Constructs an instance set to the local time defined by the specified
313         * instant evaluated using ISO chronology in the specified zone.
314         * <p>
315         * If the specified time zone is null, the default zone is used.
316         * Once the constructor is completed, the zone is no longer used.
317         *
318         * @param instant  the milliseconds from 1970-01-01T00:00:00Z
319         * @param zone  the time zone, null means default zone
320         */
321        public LocalDate(long instant, DateTimeZone zone) {
322            this(instant, ISOChronology.getInstance(zone));
323        }
324    
325        /**
326         * Constructs an instance set to the local time defined by the specified
327         * instant evaluated using the specified chronology.
328         * <p>
329         * If the chronology is null, ISO chronology in the default zone is used.
330         * Once the constructor is completed, the zone is no longer used.
331         *
332         * @param instant  the milliseconds from 1970-01-01T00:00:00Z
333         * @param chronology  the chronology, null means ISOChronology in default zone
334         */
335        public LocalDate(long instant, Chronology chronology) {
336            chronology = DateTimeUtils.getChronology(chronology);
337            
338            long localMillis = chronology.getZone().getMillisKeepLocal(DateTimeZone.UTC, instant);
339            chronology = chronology.withUTC();
340            iLocalMillis = chronology.dayOfMonth().roundFloor(localMillis);
341            iChronology = chronology;
342        }
343    
344        //-----------------------------------------------------------------------
345        /**
346         * Constructs an instance from an Object that represents a datetime.
347         * The time zone will be retrieved from the object if possible,
348         * otherwise the default time zone will be used.
349         * <p>
350         * If the object contains no chronology, <code>ISOChronology</code> is used.
351         * Once the constructor is completed, the zone is no longer used.
352         * <p>
353         * The recognised object types are defined in
354         * {@link org.joda.time.convert.ConverterManager ConverterManager} and
355         * include ReadablePartial, ReadableInstant, String, Calendar and Date.
356         * The String formats are described by {@link ISODateTimeFormat#localDateParser()}.
357         * The default String converter ignores the zone and only parses the field values.
358         *
359         * @param instant  the datetime object
360         * @throws IllegalArgumentException if the instant is invalid
361         */
362        public LocalDate(Object instant) {
363            this(instant, (Chronology) null);
364        }
365    
366        /**
367         * Constructs an instance from an Object that represents a datetime,
368         * forcing the time zone to that specified.
369         * <p>
370         * If the object contains no chronology, <code>ISOChronology</code> is used.
371         * If the specified time zone is null, the default zone is used.
372         * Once the constructor is completed, the zone is no longer used.
373         * <p>
374         * The recognised object types are defined in
375         * {@link org.joda.time.convert.ConverterManager ConverterManager} and
376         * include ReadablePartial, ReadableInstant, String, Calendar and Date.
377         * The String formats are described by {@link ISODateTimeFormat#localDateParser()}.
378         * The default String converter ignores the zone and only parses the field values.
379         *
380         * @param instant  the datetime object
381         * @param zone  the time zone
382         * @throws IllegalArgumentException if the instant is invalid
383         */
384        public LocalDate(Object instant, DateTimeZone zone) {
385            PartialConverter converter = ConverterManager.getInstance().getPartialConverter(instant);
386            Chronology chronology = converter.getChronology(instant, zone);
387            chronology = DateTimeUtils.getChronology(chronology);
388            iChronology = chronology.withUTC();
389            int[] values = converter.getPartialValues(this, instant, chronology, ISODateTimeFormat.localDateParser());
390            iLocalMillis = iChronology.getDateTimeMillis(values[0], values[1], values[2], 0);
391        }
392    
393        /**
394         * Constructs an instance from an Object that represents a datetime,
395         * using the specified chronology.
396         * <p>
397         * If the chronology is null, ISO in the default time zone is used.
398         * Once the constructor is completed, the zone is no longer used.
399         * If the instant contains a chronology, it will be ignored.
400         * For example, passing a {@code LocalDate} and a different chronology
401         * will return a date with the year/month/day from the date applied
402         * unaltered to the specified chronology.
403         * <p>
404         * The recognised object types are defined in
405         * {@link org.joda.time.convert.ConverterManager ConverterManager} and
406         * include ReadablePartial, ReadableInstant, String, Calendar and Date.
407         * The String formats are described by {@link ISODateTimeFormat#localDateParser()}.
408         * The default String converter ignores the zone and only parses the field values.
409         *
410         * @param instant  the datetime object
411         * @param chronology  the chronology
412         * @throws IllegalArgumentException if the instant is invalid
413         */
414        public LocalDate(Object instant, Chronology chronology) {
415            PartialConverter converter = ConverterManager.getInstance().getPartialConverter(instant);
416            chronology = converter.getChronology(instant, chronology);
417            chronology = DateTimeUtils.getChronology(chronology);
418            iChronology = chronology.withUTC();
419            int[] values = converter.getPartialValues(this, instant, chronology, ISODateTimeFormat.localDateParser());
420            iLocalMillis = iChronology.getDateTimeMillis(values[0], values[1], values[2], 0);
421        }
422    
423        //-----------------------------------------------------------------------
424        /**
425         * Constructs an instance set to the specified date and time
426         * using <code>ISOChronology</code>.
427         *
428         * @param year  the year
429         * @param monthOfYear  the month of the year, from 1 to 12
430         * @param dayOfMonth  the day of the month, from 1 to 31
431         */
432        public LocalDate(
433                int year,
434                int monthOfYear,
435                int dayOfMonth) {
436            this(year, monthOfYear, dayOfMonth, ISOChronology.getInstanceUTC());
437        }
438    
439        /**
440         * Constructs an instance set to the specified date and time
441         * using the specified chronology, whose zone is ignored.
442         * <p>
443         * If the chronology is null, <code>ISOChronology</code> is used.
444         *
445         * @param year  the year, valid values defined by the chronology
446         * @param monthOfYear  the month of the year, valid values defined by the chronology
447         * @param dayOfMonth  the day of the month, valid values defined by the chronology
448         * @param chronology  the chronology, null means ISOChronology in default zone
449         */
450        public LocalDate(
451                int year,
452                int monthOfYear,
453                int dayOfMonth,
454                Chronology chronology) {
455            super();
456            chronology = DateTimeUtils.getChronology(chronology).withUTC();
457            long instant = chronology.getDateTimeMillis(year, monthOfYear, dayOfMonth, 0);
458            iChronology = chronology;
459            iLocalMillis = instant;
460        }
461    
462        /**
463         * Handle broken serialization from other tools.
464         * @return the resolved object, not null
465         */
466        private Object readResolve() {
467            if (iChronology == null) {
468                return new LocalDate(iLocalMillis, ISOChronology.getInstanceUTC());
469            }
470            if (DateTimeZone.UTC.equals(iChronology.getZone()) == false) {
471                return new LocalDate(iLocalMillis, iChronology.withUTC());
472            }
473            return this;
474        }
475    
476        //-----------------------------------------------------------------------
477        /**
478         * Gets the number of fields in this partial, which is three.
479         * The supported fields are Year, MonthOfYear and DayOfMonth.
480         * Note that all fields from day and above may in fact be queried via
481         * other methods.
482         *
483         * @return the field count, three
484         */
485        public int size() {
486            return 3;
487        }
488    
489        /**
490         * Gets the field for a specific index in the chronology specified.
491         * <p>
492         * This method must not use any instance variables.
493         *
494         * @param index  the index to retrieve
495         * @param chrono  the chronology to use
496         * @return the field
497         */
498        protected DateTimeField getField(int index, Chronology chrono) {
499            switch (index) {
500                case YEAR:
501                    return chrono.year();
502                case MONTH_OF_YEAR:
503                    return chrono.monthOfYear();
504                case DAY_OF_MONTH:
505                    return chrono.dayOfMonth();
506                default:
507                    throw new IndexOutOfBoundsException("Invalid index: " + index);
508            }
509        }
510    
511        /**
512         * Gets the value of the field at the specifed index.
513         * <p>
514         * This method is required to support the <code>ReadablePartial</code>
515         * interface. The supported fields are Year, MonthOfYear and DayOfMonth.
516         * Note that all fields from day and above may in fact be queried via
517         * other methods.
518         *
519         * @param index  the index, zero to two
520         * @return the value
521         * @throws IndexOutOfBoundsException if the index is invalid
522         */
523        public int getValue(int index) {
524            switch (index) {
525                case YEAR:
526                    return getChronology().year().get(getLocalMillis());
527                case MONTH_OF_YEAR:
528                    return getChronology().monthOfYear().get(getLocalMillis());
529                case DAY_OF_MONTH:
530                    return getChronology().dayOfMonth().get(getLocalMillis());
531                default:
532                    throw new IndexOutOfBoundsException("Invalid index: " + index);
533            }
534        }
535    
536        //-----------------------------------------------------------------------
537        /**
538         * Get the value of one of the fields of a datetime.
539         * <p>
540         * This method gets the value of the specified field.
541         * For example:
542         * <pre>
543         * LocalDate dt = LocalDate.nowDefaultZone();
544         * int year = dt.get(DateTimeFieldType.year());
545         * </pre>
546         *
547         * @param fieldType  a field type, usually obtained from DateTimeFieldType, not null
548         * @return the value of that field
549         * @throws IllegalArgumentException if the field type is null or unsupported
550         */
551        public int get(DateTimeFieldType fieldType) {
552            if (fieldType == null) {
553                throw new IllegalArgumentException("The DateTimeFieldType must not be null");
554            }
555            if (isSupported(fieldType) == false) {
556                throw new IllegalArgumentException("Field '" + fieldType + "' is not supported");
557            }
558            return fieldType.getField(getChronology()).get(getLocalMillis());
559        }
560    
561        /**
562         * Checks if the field type specified is supported by this
563         * local date and chronology.
564         * This can be used to avoid exceptions in {@link #get(DateTimeFieldType)}.
565         *
566         * @param type  a field type, usually obtained from DateTimeFieldType
567         * @return true if the field type is supported
568         */
569        public boolean isSupported(DateTimeFieldType type) {
570            if (type == null) {
571                return false;
572            }
573            DurationFieldType durType = type.getDurationType();
574            if (DATE_DURATION_TYPES.contains(durType) ||
575                    durType.getField(getChronology()).getUnitMillis() >=
576                        getChronology().days().getUnitMillis()) {
577                return type.getField(getChronology()).isSupported();
578            }
579            return false;
580        }
581    
582        /**
583         * Checks if the duration type specified is supported by this
584         * local date and chronology.
585         *
586         * @param type  a duration type, usually obtained from DurationFieldType
587         * @return true if the field type is supported
588         */
589        public boolean isSupported(DurationFieldType type) {
590            if (type == null) {
591                return false;
592            }
593            DurationField field = type.getField(getChronology());
594            if (DATE_DURATION_TYPES.contains(type) ||
595                field.getUnitMillis() >= getChronology().days().getUnitMillis()) {
596                return field.isSupported();
597            }
598            return false;
599        }
600    
601        //-----------------------------------------------------------------------
602        /**
603         * Gets the local milliseconds from the Java epoch
604         * of 1970-01-01T00:00:00 (not fixed to any specific time zone).
605         * 
606         * @return the number of milliseconds since 1970-01-01T00:00:00
607         * @since 1.5 (previously private)
608         */
609        protected long getLocalMillis() {
610            return iLocalMillis;
611        }
612    
613        /**
614         * Gets the chronology of the date.
615         * 
616         * @return the Chronology that the date is using
617         */
618        public Chronology getChronology() {
619            return iChronology;
620        }
621    
622        //-----------------------------------------------------------------------
623        /**
624         * Compares this ReadablePartial with another returning true if the chronology,
625         * field types and values are equal.
626         *
627         * @param partial  an object to check against
628         * @return true if fields and values are equal
629         */
630        public boolean equals(Object partial) {
631            // override to perform faster
632            if (this == partial) {
633                return true;
634            }
635            if (partial instanceof LocalDate) {
636                LocalDate other = (LocalDate) partial;
637                if (iChronology.equals(other.iChronology)) {
638                    return iLocalMillis == other.iLocalMillis;
639                }
640            }
641            return super.equals(partial);
642        }
643    
644        /**
645         * Gets a hash code for the instant as defined in <code>ReadablePartial</code>.
646         *
647         * @return a suitable hash code
648         */
649        public int hashCode() {
650            // override for performance
651            int hash = iHash;
652            if (hash == 0) {
653                hash = iHash = super.hashCode();
654            }
655            return hash;
656        }
657    
658        /**
659         * Compares this partial with another returning an integer
660         * indicating the order.
661         * <p>
662         * The fields are compared in order, from largest to smallest.
663         * The first field that is non-equal is used to determine the result.
664         * <p>
665         * The specified object must be a partial instance whose field types
666         * match those of this partial.
667         *
668         * @param partial  an object to check against
669         * @return negative if this is less, zero if equal, positive if greater
670         * @throws ClassCastException if the partial is the wrong class
671         *  or if it has field types that don't match
672         * @throws NullPointerException if the partial is null
673         */
674        public int compareTo(ReadablePartial partial) {
675            // override to perform faster
676            if (this == partial) {
677                return 0;
678            }
679            if (partial instanceof LocalDate) {
680                LocalDate other = (LocalDate) partial;
681                if (iChronology.equals(other.iChronology)) {
682                    return (iLocalMillis < other.iLocalMillis ? -1 :
683                                (iLocalMillis == other.iLocalMillis ? 0 : 1));
684    
685                }
686            }
687            return super.compareTo(partial);
688        }
689    
690        //-----------------------------------------------------------------------
691        /**
692         * Converts this LocalDate to a full datetime at the earliest valid time
693         * for the date using the default time zone.
694         * <p>
695         * The time will normally be midnight, as that is the earliest time on
696         * any given day. However, in some time zones when Daylight Savings Time
697         * starts, there is no midnight because time jumps from 11:59 to 01:00.
698         * This method handles that situation by returning 01:00 on that date.
699         * <p>
700         * This instance is immutable and unaffected by this method call.
701         * 
702         * @return this date as a datetime at the start of the day
703         * @since 1.5
704         */
705        public DateTime toDateTimeAtStartOfDay() {
706            return toDateTimeAtStartOfDay(null);
707        }
708    
709        /**
710         * Converts this LocalDate to a full datetime at the earliest valid time
711         * for the date using the specified time zone.
712         * <p>
713         * The time will normally be midnight, as that is the earliest time on
714         * any given day. However, in some time zones when Daylight Savings Time
715         * starts, there is no midnight because time jumps from 11:59 to 01:00.
716         * This method handles that situation by returning 01:00 on that date.
717         * <p>
718         * This method uses the chronology from this instance plus the time zone
719         * specified.
720         * <p>
721         * This instance is immutable and unaffected by this method call.
722         *
723         * @param zone  the zone to use, null means default zone
724         * @return this date as a datetime at the start of the day
725         * @since 1.5
726         */
727        public DateTime toDateTimeAtStartOfDay(DateTimeZone zone) {
728            zone = DateTimeUtils.getZone(zone);
729            Chronology chrono = getChronology().withZone(zone);
730            long localMillis = getLocalMillis() + 6L * DateTimeConstants.MILLIS_PER_HOUR;
731            long instant = zone.convertLocalToUTC(localMillis, false);
732            instant = chrono.dayOfMonth().roundFloor(instant);
733            return new DateTime(instant, chrono);
734        }
735    
736        //-----------------------------------------------------------------------
737        /**
738         * Converts this LocalDate to a full datetime at midnight using the default
739         * time zone.
740         * <p>
741         * This method will throw an exception if the default time zone switches
742         * to Daylight Savings Time at midnight and this LocalDate represents
743         * that switchover date. The problem is that there is no such time as
744         * midnight on the required date, and as such an exception is thrown.
745         * <p>
746         * This instance is immutable and unaffected by this method call.
747         * 
748         * @return this date as a datetime at midnight
749         * @deprecated Use {@link #toDateTimeAtStartOfDay()} which won't throw an exception
750         */
751        @Deprecated
752        public DateTime toDateTimeAtMidnight() {
753            return toDateTimeAtMidnight(null);
754        }
755    
756        /**
757         * Converts this LocalDate to a full datetime at midnight using the
758         * specified time zone.
759         * <p>
760         * This method will throw an exception if the time zone switches
761         * to Daylight Savings Time at midnight and this LocalDate represents
762         * that switchover date. The problem is that there is no such time as
763         * midnight on the required date, and as such an exception is thrown.
764         * <p>
765         * This method uses the chronology from this instance plus the time zone
766         * specified.
767         * <p>
768         * This instance is immutable and unaffected by this method call.
769         *
770         * @param zone  the zone to use, null means default zone
771         * @return this date as a datetime at midnight
772         * @deprecated Use {@link #toDateTimeAtStartOfDay(DateTimeZone)} which won't throw an exception
773         */
774        @Deprecated
775        public DateTime toDateTimeAtMidnight(DateTimeZone zone) {
776            zone = DateTimeUtils.getZone(zone);
777            Chronology chrono = getChronology().withZone(zone);
778            return new DateTime(getYear(), getMonthOfYear(), getDayOfMonth(), 0, 0, 0, 0, chrono);
779        }
780    
781        //-----------------------------------------------------------------------
782        /**
783         * Converts this LocalDate to a full datetime using the default time zone
784         * setting the date fields from this instance and the time fields from
785         * the current time.
786         * <p>
787         * This method will throw an exception if the datetime that would be
788         * created does not exist when the time zone is taken into account.
789         * <p>
790         * This instance is immutable and unaffected by this method call.
791         *
792         * @return this date as a datetime with the time as the current time
793         */
794        public DateTime toDateTimeAtCurrentTime() {
795            return toDateTimeAtCurrentTime(null);
796        }
797    
798        /**
799         * Converts this LocalDate to a full datetime using the specified time zone
800         * setting the date fields from this instance and the time fields from
801         * the current time.
802         * <p>
803         * This method uses the chronology from this instance plus the time zone
804         * specified.
805         * <p>
806         * This method will throw an exception if the datetime that would be
807         * created does not exist when the time zone is taken into account.
808         * <p>
809         * This instance is immutable and unaffected by this method call.
810         *
811         * @param zone  the zone to use, null means default zone
812         * @return this date as a datetime with the time as the current time
813         */
814        public DateTime toDateTimeAtCurrentTime(DateTimeZone zone) {
815            zone = DateTimeUtils.getZone(zone);
816            Chronology chrono = getChronology().withZone(zone);
817            long instantMillis = DateTimeUtils.currentTimeMillis();
818            long resolved = chrono.set(this, instantMillis);
819            return new DateTime(resolved, chrono);
820        }
821    
822        //-----------------------------------------------------------------------
823        /**
824         * Converts this LocalDate to a DateMidnight in the default time zone.
825         * <p>
826         * As from v1.5, you are recommended to avoid DateMidnight and use
827         * {@link #toDateTimeAtStartOfDay()} instead because of the exception
828         * detailed below.
829         * <p>
830         * This method will throw an exception if the default time zone switches
831         * to Daylight Savings Time at midnight and this LocalDate represents
832         * that switchover date. The problem is that there is no such time as
833         * midnight on the required date, and as such an exception is thrown.
834         * <p>
835         * This instance is immutable and unaffected by this method call.
836         *
837         * @return the DateMidnight instance in the default zone
838         */
839        public DateMidnight toDateMidnight() {
840            return toDateMidnight(null);
841        }
842    
843        /**
844         * Converts this LocalDate to a DateMidnight.
845         * <p>
846         * As from v1.5, you are recommended to avoid DateMidnight and use
847         * {@link #toDateTimeAtStartOfDay()} instead because of the exception
848         * detailed below.
849         * <p>
850         * This method will throw an exception if the time zone switches
851         * to Daylight Savings Time at midnight and this LocalDate represents
852         * that switchover date. The problem is that there is no such time as
853         * midnight on the required date, and as such an exception is thrown.
854         * <p>
855         * This instance is immutable and unaffected by this method call.
856         *
857         * @param zone  the zone to get the DateMidnight in, null means default zone
858         * @return the DateMidnight instance
859         */
860        public DateMidnight toDateMidnight(DateTimeZone zone) {
861            zone = DateTimeUtils.getZone(zone);
862            Chronology chrono = getChronology().withZone(zone);
863            return new DateMidnight(getYear(), getMonthOfYear(), getDayOfMonth(), chrono);
864        }
865    
866        //-----------------------------------------------------------------------
867        /**
868         * Converts this object to a LocalDateTime using a LocalTime to fill in
869         * the missing fields.
870         * <p>
871         * The resulting chronology is determined by the chronology of this
872         * LocalDate. The chronology of the time must also match.
873         * If the time is null an exception is thrown.
874         * <p>
875         * This instance is immutable and unaffected by this method call.
876         *
877         * @param time  the time of day to use, must not be null
878         * @return the LocalDateTime instance
879         * @throws IllegalArgumentException if the time is null
880         * @throws IllegalArgumentException if the chronology of the time does not match
881         * @since 1.5
882         */
883        public LocalDateTime toLocalDateTime(LocalTime time) {
884            if (time == null) {
885                throw new IllegalArgumentException("The time must not be null");
886            }
887            if (getChronology() != time.getChronology()) {
888                throw new IllegalArgumentException("The chronology of the time does not match");
889            }
890            long localMillis = getLocalMillis() + time.getLocalMillis();
891            return new LocalDateTime(localMillis, getChronology());
892        }
893    
894        //-----------------------------------------------------------------------
895        /**
896         * Converts this object to a DateTime using a LocalTime to fill in the
897         * missing fields and using the default time zone.
898         * <p>
899         * The resulting chronology is determined by the chronology of this
900         * LocalDate. The chronology of the time must match.
901         * If the time is null, the current time in the date's chronology is used.
902         * <p>
903         * This method will throw an exception if the datetime that would be
904         * created does not exist when the time zone is taken into account.
905         * <p>
906         * This instance is immutable and unaffected by this method call.
907         *
908         * @param time  the time of day to use, null means current time
909         * @return the DateTime instance
910         * @throws IllegalArgumentException if the chronology of the time does not match
911         */
912        public DateTime toDateTime(LocalTime time) {
913            return toDateTime(time, null);
914        }
915    
916        /**
917         * Converts this object to a DateTime using a LocalTime to fill in the
918         * missing fields.
919         * <p>
920         * The resulting chronology is determined by the chronology of this
921         * LocalDate plus the time zone. The chronology of the time must match.
922         * If the time is null, the current time in the date's chronology is used.
923         * <p>
924         * This method will throw an exception if the datetime that would be
925         * created does not exist when the time zone is taken into account.
926         * <p>
927         * This instance is immutable and unaffected by this method call.
928         *
929         * @param time  the time of day to use, null means current time
930         * @param zone  the zone to get the DateTime in, null means default
931         * @return the DateTime instance
932         * @throws IllegalArgumentException if the chronology of the time does not match
933         */
934        public DateTime toDateTime(LocalTime time, DateTimeZone zone) {
935            if (time != null && getChronology() != time.getChronology()) {
936                throw new IllegalArgumentException("The chronology of the time does not match");
937            }
938            Chronology chrono = getChronology().withZone(zone);
939            long instant = DateTimeUtils.currentTimeMillis();
940            instant = chrono.set(this, instant);
941            if (time != null) {
942                instant = chrono.set(time, instant);
943            }
944            return new DateTime(instant, chrono);
945        }
946    
947        //-----------------------------------------------------------------------
948        /**
949         * Converts this object to an Interval representing the whole day
950         * in the default time zone.
951         * <p>
952         * The interval may have more or less than 24 hours if this is a daylight
953         * savings cutover date.
954         * <p>
955         * This instance is immutable and unaffected by this method call.
956         *
957         * @return a interval over the day
958         */
959        public Interval toInterval() {
960            return toInterval(null);
961        }
962    
963        /**
964         * Converts this object to an Interval representing the whole day.
965         * <p>
966         * The interval may have more or less than 24 hours if this is a daylight
967         * savings cutover date.
968         * <p>
969         * This instance is immutable and unaffected by this method call.
970         *
971         * @param zone  the zone to get the Interval in, null means default
972         * @return a interval over the day
973         */
974        public Interval toInterval(DateTimeZone zone) {
975            zone = DateTimeUtils.getZone(zone);
976            DateTime start = toDateTimeAtStartOfDay(zone);
977            DateTime end = plusDays(1).toDateTimeAtStartOfDay(zone);
978            return new Interval(start, end);
979        }
980    
981        //-----------------------------------------------------------------------
982        /**
983         * Get the date time as a <code>java.util.Date</code>.
984         * <p>
985         * The <code>Date</code> object created has exactly the same year, month and day
986         * as this date. The time will be set to the earliest valid time for that date.
987         * <p>
988         * Converting to a JDK Date is full of complications as the JDK Date constructor
989         * doesn't behave as you might expect around DST transitions. This method works
990         * by taking a first guess and then adjusting the JDK date until it has the
991         * earliest valid instant. This also handles the situation where the JDK time
992         * zone data differs from the Joda-Time time zone data.
993         *
994         * @return a Date initialised with this date, never null
995         * @since 2.0
996         */
997        @SuppressWarnings("deprecation")
998        public Date toDate() {
999            int dom = getDayOfMonth();
1000            Date date = new Date(getYear() - 1900, getMonthOfYear() - 1, dom);
1001            LocalDate check = LocalDate.fromDateFields(date);
1002            if (check.isBefore(this)) {
1003                // DST gap (no midnight)
1004                // move forward in units of one hour until date correct
1005                while (check.equals(this) == false) {
1006                    date.setTime(date.getTime() + 3600000);
1007                    check = LocalDate.fromDateFields(date);
1008                }
1009                // move back in units of one second until date wrong
1010                while (date.getDate() == dom) {
1011                    date.setTime(date.getTime() - 1000);
1012                }
1013                // fix result
1014                date.setTime(date.getTime() + 1000);
1015            } else if (check.equals(this)) {
1016                // check for DST overlap (two midnights)
1017                Date earlier = new Date(date.getTime() - TimeZone.getDefault().getDSTSavings());
1018                if (earlier.getDate() == dom) {
1019                    date = earlier;
1020                }
1021            }
1022            return date;
1023        }
1024    
1025        //-----------------------------------------------------------------------
1026        /**
1027         * Returns a copy of this date with different local millis.
1028         * <p>
1029         * The returned object will be a new instance of the same type.
1030         * Only the millis will change, the chronology is kept.
1031         * The returned object will be either be a new instance or <code>this</code>.
1032         *
1033         * @param newMillis  the new millis, from 1970-01-01T00:00:00
1034         * @return a copy of this date with different millis
1035         */
1036        LocalDate withLocalMillis(long newMillis) {
1037            newMillis = iChronology.dayOfMonth().roundFloor(newMillis);
1038            return (newMillis == getLocalMillis() ? this : new LocalDate(newMillis, getChronology()));
1039        }
1040    
1041        //-----------------------------------------------------------------------
1042        /**
1043         * Returns a copy of this date with the partial set of fields replacing
1044         * those from this instance.
1045         * <p>
1046         * For example, if the partial contains a year and a month then those two
1047         * fields will be changed in the returned instance.
1048         * Unsupported fields are ignored.
1049         * If the partial is null, then <code>this</code> is returned.
1050         *
1051         * @param partial  the partial set of fields to apply to this date, null ignored
1052         * @return a copy of this date with a different set of fields
1053         * @throws IllegalArgumentException if any value is invalid
1054         */
1055        public LocalDate withFields(ReadablePartial partial) {
1056            if (partial == null) {
1057                return this;
1058            }
1059            return withLocalMillis(getChronology().set(partial, getLocalMillis()));
1060        }
1061    
1062        /**
1063         * Returns a copy of this date with the specified field set to a new value.
1064         * <p>
1065         * For example, if the field type is <code>monthOfYear</code> then the
1066         * month of year field will be changed in the returned instance.
1067         * If the field type is null, then <code>this</code> is returned.
1068         * <p>
1069         * These two lines are equivalent:
1070         * <pre>
1071         * LocalDate updated = dt.withDayOfMonth(6);
1072         * LocalDate updated = dt.withField(DateTimeFieldType.dayOfMonth(), 6);
1073         * </pre>
1074         *
1075         * @param fieldType  the field type to set, not null
1076         * @param value  the value to set
1077         * @return a copy of this date with the field set
1078         * @throws IllegalArgumentException if the field is null or unsupported
1079         */
1080        public LocalDate withField(DateTimeFieldType fieldType, int value) {
1081            if (fieldType == null) {
1082                throw new IllegalArgumentException("Field must not be null");
1083            }
1084            if (isSupported(fieldType) == false) {
1085                throw new IllegalArgumentException("Field '" + fieldType + "' is not supported");
1086            }
1087            long instant = fieldType.getField(getChronology()).set(getLocalMillis(), value);
1088            return withLocalMillis(instant);
1089        }
1090    
1091        /**
1092         * Returns a copy of this date with the value of the specified field increased.
1093         * <p>
1094         * If the addition is zero or the field is null, then <code>this</code> is returned.
1095         * <p>
1096         * These three lines are equivalent:
1097         * <pre>
1098         * LocalDate added = dt.withFieldAdded(DurationFieldType.years(), 6);
1099         * LocalDate added = dt.plusYears(6);
1100         * LocalDate added = dt.plus(Period.years(6));
1101         * </pre>
1102         *
1103         * @param fieldType  the field type to add to, not null
1104         * @param amount  the amount to add
1105         * @return a copy of this date with the field updated
1106         * @throws IllegalArgumentException if the field is null or unsupported
1107         * @throws ArithmeticException if the result exceeds the internal capacity
1108         */
1109        public LocalDate withFieldAdded(DurationFieldType fieldType, int amount) {
1110            if (fieldType == null) {
1111                throw new IllegalArgumentException("Field must not be null");
1112            }
1113            if (isSupported(fieldType) == false) {
1114                throw new IllegalArgumentException("Field '" + fieldType + "' is not supported");
1115            }
1116            if (amount == 0) {
1117                return this;
1118            }
1119            long instant = fieldType.getField(getChronology()).add(getLocalMillis(), amount);
1120            return withLocalMillis(instant);
1121        }
1122    
1123        //-----------------------------------------------------------------------
1124        /**
1125         * Returns a copy of this date with the specified period added.
1126         * <p>
1127         * If the addition is zero, then <code>this</code> is returned.
1128         * <p>
1129         * This method is typically used to add multiple copies of complex
1130         * period instances. Adding one field is best achieved using methods
1131         * like {@link #withFieldAdded(DurationFieldType, int)}
1132         * or {@link #plusYears(int)}.
1133         * <p>
1134         * Unsupported time fields are ignored, thus adding a period of 24 hours
1135         * will not have any effect.
1136         *
1137         * @param period  the period to add to this one, null means zero
1138         * @param scalar  the amount of times to add, such as -1 to subtract once
1139         * @return a copy of this date with the period added
1140         * @throws ArithmeticException if the result exceeds the internal capacity
1141         */
1142        public LocalDate withPeriodAdded(ReadablePeriod period, int scalar) {
1143            if (period == null || scalar == 0) {
1144                return this;
1145            }
1146            long instant = getLocalMillis();
1147            Chronology chrono = getChronology();
1148            for (int i = 0; i < period.size(); i++) {
1149                long value = FieldUtils.safeMultiply(period.getValue(i), scalar);
1150                DurationFieldType type = period.getFieldType(i);
1151                if (isSupported(type)) {
1152                    instant = type.getField(chrono).add(instant, value);
1153                }
1154            }
1155            return withLocalMillis(instant);
1156        }
1157    
1158        //-----------------------------------------------------------------------
1159        /**
1160         * Returns a copy of this date with the specified period added.
1161         * <p>
1162         * If the amount is zero or null, then <code>this</code> is returned.
1163         * <p>
1164         * This method is typically used to add complex period instances.
1165         * Adding one field is best achieved using methods
1166         * like {@link #plusYears(int)}.
1167         * <p>
1168         * Unsupported time fields are ignored, thus adding a period of 24 hours
1169         * will not have any effect.
1170         *
1171         * @param period  the period to add to this one, null means zero
1172         * @return a copy of this date with the period added
1173         * @throws ArithmeticException if the result exceeds the internal capacity
1174         */
1175        public LocalDate plus(ReadablePeriod period) {
1176            return withPeriodAdded(period, 1);
1177        }
1178    
1179        //-----------------------------------------------------------------------
1180        /**
1181         * Returns a copy of this date plus the specified number of years.
1182         * <p>
1183         * This adds the specified number of years to the date.
1184         * If adding years makes the day-of-month invalid, it is adjusted to the last valid day in the month.
1185         * This LocalDate instance is immutable and unaffected by this method call.
1186         * <p>
1187         * The following three lines are identical in effect:
1188         * <pre>
1189         * LocalDate added = dt.plusYears(6);
1190         * LocalDate added = dt.plus(Period.years(6));
1191         * LocalDate added = dt.withFieldAdded(DurationFieldType.years(), 6);
1192         * </pre>
1193         *
1194         * @param years  the amount of years to add, may be negative
1195         * @return the new LocalDate plus the increased years
1196         */
1197        public LocalDate plusYears(int years) {
1198            if (years == 0) {
1199                return this;
1200            }
1201            long instant = getChronology().years().add(getLocalMillis(), years);
1202            return withLocalMillis(instant);
1203        }
1204    
1205        /**
1206         * Returns a copy of this date plus the specified number of months.
1207         * <p>
1208         * This adds the specified number of months to the date.
1209         * The addition may change the year, but the day-of-month is normally unchanged.
1210         * If adding months makes the day-of-month invalid, it is adjusted to the last valid day in the month.
1211         * This LocalDate instance is immutable and unaffected by this method call.
1212         * <p>
1213         * The following three lines are identical in effect:
1214         * <pre>
1215         * LocalDate added = dt.plusMonths(6);
1216         * LocalDate added = dt.plus(Period.months(6));
1217         * LocalDate added = dt.withFieldAdded(DurationFieldType.months(), 6);
1218         * </pre>
1219         *
1220         * @param months  the amount of months to add, may be negative
1221         * @return the new LocalDate plus the increased months
1222         */
1223        public LocalDate plusMonths(int months) {
1224            if (months == 0) {
1225                return this;
1226            }
1227            long instant = getChronology().months().add(getLocalMillis(), months);
1228            return withLocalMillis(instant);
1229        }
1230    
1231        /**
1232         * Returns a copy of this date plus the specified number of weeks.
1233         * <p>
1234         * This LocalDate instance is immutable and unaffected by this method call.
1235         * <p>
1236         * The following three lines are identical in effect:
1237         * <pre>
1238         * LocalDate added = dt.plusWeeks(6);
1239         * LocalDate added = dt.plus(Period.weeks(6));
1240         * LocalDate added = dt.withFieldAdded(DurationFieldType.weeks(), 6);
1241         * </pre>
1242         *
1243         * @param weeks  the amount of weeks to add, may be negative
1244         * @return the new LocalDate plus the increased weeks
1245         */
1246        public LocalDate plusWeeks(int weeks) {
1247            if (weeks == 0) {
1248                return this;
1249            }
1250            long instant = getChronology().weeks().add(getLocalMillis(), weeks);
1251            return withLocalMillis(instant);
1252        }
1253    
1254        /**
1255         * Returns a copy of this date plus the specified number of days.
1256         * <p>
1257         * This LocalDate instance is immutable and unaffected by this method call.
1258         * <p>
1259         * The following three lines are identical in effect:
1260         * <pre>
1261         * LocalDate added = dt.plusDays(6);
1262         * LocalDate added = dt.plus(Period.days(6));
1263         * LocalDate added = dt.withFieldAdded(DurationFieldType.days(), 6);
1264         * </pre>
1265         *
1266         * @param days  the amount of days to add, may be negative
1267         * @return the new LocalDate plus the increased days
1268         */
1269        public LocalDate plusDays(int days) {
1270            if (days == 0) {
1271                return this;
1272            }
1273            long instant = getChronology().days().add(getLocalMillis(), days);
1274            return withLocalMillis(instant);
1275        }
1276    
1277        //-----------------------------------------------------------------------
1278        /**
1279         * Returns a copy of this date with the specified period taken away.
1280         * <p>
1281         * If the amount is zero or null, then <code>this</code> is returned.
1282         * <p>
1283         * This method is typically used to subtract complex period instances.
1284         * Subtracting one field is best achieved using methods
1285         * like {@link #minusYears(int)}.
1286         * <p>
1287         * Unsupported time fields are ignored, thus subtracting a period of 24 hours
1288         * will not have any effect.
1289         *
1290         * @param period  the period to reduce this instant by
1291         * @return a copy of this LocalDate with the period taken away
1292         * @throws ArithmeticException if the result exceeds the internal capacity
1293         */
1294        public LocalDate minus(ReadablePeriod period) {
1295            return withPeriodAdded(period, -1);
1296        }
1297    
1298        //-----------------------------------------------------------------------
1299        /**
1300         * Returns a copy of this date minus the specified number of years.
1301         * <p>
1302         * This subtracts the specified number of years from the date.
1303         * If subtracting years makes the day-of-month invalid, it is adjusted to the last valid day in the month.
1304         * This LocalDate instance is immutable and unaffected by this method call.
1305         * <p>
1306         * The following three lines are identical in effect:
1307         * <pre>
1308         * LocalDate subtracted = dt.minusYears(6);
1309         * LocalDate subtracted = dt.minus(Period.years(6));
1310         * LocalDate subtracted = dt.withFieldAdded(DurationFieldType.years(), -6);
1311         * </pre>
1312         *
1313         * @param years  the amount of years to subtract, may be negative
1314         * @return the new LocalDate minus the increased years
1315         */
1316        public LocalDate minusYears(int years) {
1317            if (years == 0) {
1318                return this;
1319            }
1320            long instant = getChronology().years().subtract(getLocalMillis(), years);
1321            return withLocalMillis(instant);
1322        }
1323    
1324        /**
1325         * Returns a copy of this date minus the specified number of months.
1326         * <p>
1327         * This subtracts the specified number of months from the date.
1328         * The subtraction may change the year, but the day-of-month is normally unchanged.
1329         * If subtracting months makes the day-of-month invalid, it is adjusted to the last valid day in the month.
1330         * This LocalDate instance is immutable and unaffected by this method call.
1331         * <p>
1332         * The following three lines are identical in effect:
1333         * <pre>
1334         * LocalDate subtracted = dt.minusMonths(6);
1335         * LocalDate subtracted = dt.minus(Period.months(6));
1336         * LocalDate subtracted = dt.withFieldAdded(DurationFieldType.months(), -6);
1337         * </pre>
1338         *
1339         * @param months  the amount of months to subtract, may be negative
1340         * @return the new LocalDate minus the increased months
1341         */
1342        public LocalDate minusMonths(int months) {
1343            if (months == 0) {
1344                return this;
1345            }
1346            long instant = getChronology().months().subtract(getLocalMillis(), months);
1347            return withLocalMillis(instant);
1348        }
1349    
1350        /**
1351         * Returns a copy of this date minus the specified number of weeks.
1352         * <p>
1353         * This LocalDate instance is immutable and unaffected by this method call.
1354         * <p>
1355         * The following three lines are identical in effect:
1356         * <pre>
1357         * LocalDate subtracted = dt.minusWeeks(6);
1358         * LocalDate subtracted = dt.minus(Period.weeks(6));
1359         * LocalDate subtracted = dt.withFieldAdded(DurationFieldType.weeks(), -6);
1360         * </pre>
1361         *
1362         * @param weeks  the amount of weeks to subtract, may be negative
1363         * @return the new LocalDate minus the increased weeks
1364         */
1365        public LocalDate minusWeeks(int weeks) {
1366            if (weeks == 0) {
1367                return this;
1368            }
1369            long instant = getChronology().weeks().subtract(getLocalMillis(), weeks);
1370            return withLocalMillis(instant);
1371        }
1372    
1373        /**
1374         * Returns a copy of this date minus the specified number of days.
1375         * <p>
1376         * This LocalDate instance is immutable and unaffected by this method call.
1377         * <p>
1378         * The following three lines are identical in effect:
1379         * <pre>
1380         * LocalDate subtracted = dt.minusDays(6);
1381         * LocalDate subtracted = dt.minus(Period.days(6));
1382         * LocalDate subtracted = dt.withFieldAdded(DurationFieldType.days(), -6);
1383         * </pre>
1384         *
1385         * @param days  the amount of days to subtract, may be negative
1386         * @return the new LocalDate minus the increased days
1387         */
1388        public LocalDate minusDays(int days) {
1389            if (days == 0) {
1390                return this;
1391            }
1392            long instant = getChronology().days().subtract(getLocalMillis(), days);
1393            return withLocalMillis(instant);
1394        }
1395    
1396        //-----------------------------------------------------------------------
1397        /**
1398         * Gets the property object for the specified type, which contains many
1399         * useful methods.
1400         *
1401         * @param fieldType  the field type to get the chronology for
1402         * @return the property object
1403         * @throws IllegalArgumentException if the field is null or unsupported
1404         */
1405        public Property property(DateTimeFieldType fieldType) {
1406            if (fieldType == null) {
1407                throw new IllegalArgumentException("The DateTimeFieldType must not be null");
1408            }
1409            if (isSupported(fieldType) == false) {
1410                throw new IllegalArgumentException("Field '" + fieldType + "' is not supported");
1411            }
1412            return new Property(this, fieldType.getField(getChronology()));
1413        }
1414    
1415        //-----------------------------------------------------------------------
1416        /**
1417         * Get the era field value.
1418         *
1419         * @return the era
1420         */
1421        public int getEra() {
1422            return getChronology().era().get(getLocalMillis());
1423        }
1424    
1425        /**
1426         * Get the year of era field value.
1427         *
1428         * @return the year of era
1429         */
1430        public int getCenturyOfEra() {
1431            return getChronology().centuryOfEra().get(getLocalMillis());
1432        }
1433    
1434        /**
1435         * Get the year of era field value.
1436         *
1437         * @return the year of era
1438         */
1439        public int getYearOfEra() {
1440            return getChronology().yearOfEra().get(getLocalMillis());
1441        }
1442    
1443        /**
1444         * Get the year of century field value.
1445         *
1446         * @return the year of century
1447         */
1448        public int getYearOfCentury() {
1449            return getChronology().yearOfCentury().get(getLocalMillis());
1450        }
1451    
1452        /**
1453         * Get the year field value.
1454         *
1455         * @return the year
1456         */
1457        public int getYear() {
1458            return getChronology().year().get(getLocalMillis());
1459        }
1460    
1461        /**
1462         * Get the weekyear field value.
1463         * <p>
1464         * The weekyear is the year that matches with the weekOfWeekyear field.
1465         * In the standard ISO8601 week algorithm, the first week of the year
1466         * is that in which at least 4 days are in the year. As a result of this
1467         * definition, day 1 of the first week may be in the previous year.
1468         * The weekyear allows you to query the effective year for that day.
1469         *
1470         * @return the weekyear
1471         */
1472        public int getWeekyear() {
1473            return getChronology().weekyear().get(getLocalMillis());
1474        }
1475    
1476        /**
1477         * Get the month of year field value.
1478         *
1479         * @return the month of year
1480         */
1481        public int getMonthOfYear() {
1482            return getChronology().monthOfYear().get(getLocalMillis());
1483        }
1484    
1485        /**
1486         * Get the week of weekyear field value.
1487         * <p>
1488         * This field is associated with the "weekyear" via {@link #getWeekyear()}.
1489         * In the standard ISO8601 week algorithm, the first week of the year
1490         * is that in which at least 4 days are in the year. As a result of this
1491         * definition, day 1 of the first week may be in the previous year.
1492         *
1493         * @return the week of a week based year
1494         */
1495        public int getWeekOfWeekyear() {
1496            return getChronology().weekOfWeekyear().get(getLocalMillis());
1497        }
1498    
1499        /**
1500         * Get the day of year field value.
1501         *
1502         * @return the day of year
1503         */
1504        public int getDayOfYear() {
1505            return getChronology().dayOfYear().get(getLocalMillis());
1506        }
1507    
1508        /**
1509         * Get the day of month field value.
1510         * <p>
1511         * The values for the day of month are defined in {@link org.joda.time.DateTimeConstants}.
1512         *
1513         * @return the day of month
1514         */
1515        public int getDayOfMonth() {
1516            return getChronology().dayOfMonth().get(getLocalMillis());
1517        }
1518    
1519        /**
1520         * Get the day of week field value.
1521         * <p>
1522         * The values for the day of week are defined in {@link org.joda.time.DateTimeConstants}.
1523         *
1524         * @return the day of week
1525         */
1526        public int getDayOfWeek() {
1527            return getChronology().dayOfWeek().get(getLocalMillis());
1528        }
1529    
1530        //-----------------------------------------------------------------------
1531        /**
1532         * Returns a copy of this date with the era field updated.
1533         * <p>
1534         * LocalDate is immutable, so there are no set methods.
1535         * Instead, this method returns a new instance with the value of
1536         * era changed.
1537         *
1538         * @param era  the era to set
1539         * @return a copy of this object with the field set
1540         * @throws IllegalArgumentException if the value is invalid
1541         */
1542        public LocalDate withEra(int era) {
1543            return withLocalMillis(getChronology().era().set(getLocalMillis(), era));
1544        }
1545    
1546        /**
1547         * Returns a copy of this date with the century of era field updated.
1548         * <p>
1549         * LocalDate is immutable, so there are no set methods.
1550         * Instead, this method returns a new instance with the value of
1551         * century of era changed.
1552         *
1553         * @param centuryOfEra  the centurey of era to set
1554         * @return a copy of this object with the field set
1555         * @throws IllegalArgumentException if the value is invalid
1556         */
1557        public LocalDate withCenturyOfEra(int centuryOfEra) {
1558            return withLocalMillis(getChronology().centuryOfEra().set(getLocalMillis(), centuryOfEra));
1559        }
1560    
1561        /**
1562         * Returns a copy of this date with the year of era field updated.
1563         * <p>
1564         * LocalDate is immutable, so there are no set methods.
1565         * Instead, this method returns a new instance with the value of
1566         * year of era changed.
1567         *
1568         * @param yearOfEra  the year of era to set
1569         * @return a copy of this object with the field set
1570         * @throws IllegalArgumentException if the value is invalid
1571         */
1572        public LocalDate withYearOfEra(int yearOfEra) {
1573            return withLocalMillis(getChronology().yearOfEra().set(getLocalMillis(), yearOfEra));
1574        }
1575    
1576        /**
1577         * Returns a copy of this date with the year of century field updated.
1578         * <p>
1579         * LocalDate is immutable, so there are no set methods.
1580         * Instead, this method returns a new instance with the value of
1581         * year of century changed.
1582         *
1583         * @param yearOfCentury  the year of century to set
1584         * @return a copy of this object with the field set
1585         * @throws IllegalArgumentException if the value is invalid
1586         */
1587        public LocalDate withYearOfCentury(int yearOfCentury) {
1588            return withLocalMillis(getChronology().yearOfCentury().set(getLocalMillis(), yearOfCentury));
1589        }
1590    
1591        /**
1592         * Returns a copy of this date with the year field updated.
1593         * <p>
1594         * LocalDate is immutable, so there are no set methods.
1595         * Instead, this method returns a new instance with the value of
1596         * year changed.
1597         *
1598         * @param year  the year to set
1599         * @return a copy of this object with the field set
1600         * @throws IllegalArgumentException if the value is invalid
1601         */
1602        public LocalDate withYear(int year) {
1603            return withLocalMillis(getChronology().year().set(getLocalMillis(), year));
1604        }
1605    
1606        /**
1607         * Returns a copy of this date with the weekyear field updated.
1608         * <p>
1609         * The weekyear is the year that matches with the weekOfWeekyear field.
1610         * In the standard ISO8601 week algorithm, the first week of the year
1611         * is that in which at least 4 days are in the year. As a result of this
1612         * definition, day 1 of the first week may be in the previous year.
1613         * The weekyear allows you to query the effective year for that day.
1614         * <p>
1615         * LocalDate is immutable, so there are no set methods.
1616         * Instead, this method returns a new instance with the value of
1617         * weekyear changed.
1618         *
1619         * @param weekyear  the weekyear to set
1620         * @return a copy of this object with the field set
1621         * @throws IllegalArgumentException if the value is invalid
1622         */
1623        public LocalDate withWeekyear(int weekyear) {
1624            return withLocalMillis(getChronology().weekyear().set(getLocalMillis(), weekyear));
1625        }
1626    
1627        /**
1628         * Returns a copy of this date with the month of year field updated.
1629         * <p>
1630         * LocalDate is immutable, so there are no set methods.
1631         * Instead, this method returns a new instance with the value of
1632         * month of year changed.
1633         *
1634         * @param monthOfYear  the month of year to set
1635         * @return a copy of this object with the field set
1636         * @throws IllegalArgumentException if the value is invalid
1637         */
1638        public LocalDate withMonthOfYear(int monthOfYear) {
1639            return withLocalMillis(getChronology().monthOfYear().set(getLocalMillis(), monthOfYear));
1640        }
1641    
1642        /**
1643         * Returns a copy of this date with the week of weekyear field updated.
1644         * <p>
1645         * This field is associated with the "weekyear" via {@link #withWeekyear(int)}.
1646         * In the standard ISO8601 week algorithm, the first week of the year
1647         * is that in which at least 4 days are in the year. As a result of this
1648         * definition, day 1 of the first week may be in the previous year.
1649         * <p>
1650         * LocalDate is immutable, so there are no set methods.
1651         * Instead, this method returns a new instance with the value of
1652         * week of weekyear changed.
1653         *
1654         * @param weekOfWeekyear  the week of weekyear to set
1655         * @return a copy of this object with the field set
1656         * @throws IllegalArgumentException if the value is invalid
1657         */
1658        public LocalDate withWeekOfWeekyear(int weekOfWeekyear) {
1659            return withLocalMillis(getChronology().weekOfWeekyear().set(getLocalMillis(), weekOfWeekyear));
1660        }
1661    
1662        /**
1663         * Returns a copy of this date with the day of year field updated.
1664         * <p>
1665         * LocalDate is immutable, so there are no set methods.
1666         * Instead, this method returns a new instance with the value of
1667         * day of year changed.
1668         *
1669         * @param dayOfYear  the day of year to set
1670         * @return a copy of this object with the field set
1671         * @throws IllegalArgumentException if the value is invalid
1672         */
1673        public LocalDate withDayOfYear(int dayOfYear) {
1674            return withLocalMillis(getChronology().dayOfYear().set(getLocalMillis(), dayOfYear));
1675        }
1676    
1677        /**
1678         * Returns a copy of this date with the day of month field updated.
1679         * <p>
1680         * LocalDate is immutable, so there are no set methods.
1681         * Instead, this method returns a new instance with the value of
1682         * day of month changed.
1683         *
1684         * @param dayOfMonth  the day of month to set
1685         * @return a copy of this object with the field set
1686         * @throws IllegalArgumentException if the value is invalid
1687         */
1688        public LocalDate withDayOfMonth(int dayOfMonth) {
1689            return withLocalMillis(getChronology().dayOfMonth().set(getLocalMillis(), dayOfMonth));
1690        }
1691    
1692        /**
1693         * Returns a copy of this date with the day of week field updated.
1694         * <p>
1695         * LocalDate is immutable, so there are no set methods.
1696         * Instead, this method returns a new instance with the value of
1697         * day of week changed.
1698         *
1699         * @param dayOfWeek  the day of week to set
1700         * @return a copy of this object with the field set
1701         * @throws IllegalArgumentException if the value is invalid
1702         */
1703        public LocalDate withDayOfWeek(int dayOfWeek) {
1704            return withLocalMillis(getChronology().dayOfWeek().set(getLocalMillis(), dayOfWeek));
1705        }
1706    
1707        //-----------------------------------------------------------------------
1708        /**
1709         * Get the era property which provides access to advanced functionality.
1710         *
1711         * @return the era property
1712         */
1713        public Property era() {
1714            return new Property(this, getChronology().era());
1715        }
1716    
1717        /**
1718         * Get the century of era property which provides access to advanced functionality.
1719         *
1720         * @return the year of era property
1721         */
1722        public Property centuryOfEra() {
1723            return new Property(this, getChronology().centuryOfEra());
1724        }
1725    
1726        /**
1727         * Get the year of century property which provides access to advanced functionality.
1728         *
1729         * @return the year of era property
1730         */
1731        public Property yearOfCentury() {
1732            return new Property(this, getChronology().yearOfCentury());
1733        }
1734    
1735        /**
1736         * Get the year of era property which provides access to advanced functionality.
1737         *
1738         * @return the year of era property
1739         */
1740        public Property yearOfEra() {
1741            return new Property(this, getChronology().yearOfEra());
1742        }
1743    
1744        /**
1745         * Get the year property which provides access to advanced functionality.
1746         *
1747         * @return the year property
1748         */
1749        public Property year() {
1750            return new Property(this, getChronology().year());
1751        }
1752    
1753        /**
1754         * Get the weekyear property which provides access to advanced functionality.
1755         *
1756         * @return the weekyear property
1757         */
1758        public Property weekyear() {
1759            return new Property(this, getChronology().weekyear());
1760        }
1761    
1762        /**
1763         * Get the month of year property which provides access to advanced functionality.
1764         *
1765         * @return the month of year property
1766         */
1767        public Property monthOfYear() {
1768            return new Property(this, getChronology().monthOfYear());
1769        }
1770    
1771        /**
1772         * Get the week of a week based year property which provides access to advanced functionality.
1773         *
1774         * @return the week of a week based year property
1775         */
1776        public Property weekOfWeekyear() {
1777            return new Property(this, getChronology().weekOfWeekyear());
1778        }
1779    
1780        /**
1781         * Get the day of year property which provides access to advanced functionality.
1782         *
1783         * @return the day of year property
1784         */
1785        public Property dayOfYear() {
1786            return new Property(this, getChronology().dayOfYear());
1787        }
1788    
1789        /**
1790         * Get the day of month property which provides access to advanced functionality.
1791         *
1792         * @return the day of month property
1793         */
1794        public Property dayOfMonth() {
1795            return new Property(this, getChronology().dayOfMonth());
1796        }
1797    
1798        /**
1799         * Get the day of week property which provides access to advanced functionality.
1800         *
1801         * @return the day of week property
1802         */
1803        public Property dayOfWeek() {
1804            return new Property(this, getChronology().dayOfWeek());
1805        }
1806    
1807        //-----------------------------------------------------------------------
1808        /**
1809         * Output the date time in ISO8601 format (yyyy-MM-dd).
1810         *
1811         * @return ISO8601 time formatted string.
1812         */
1813        @ToString
1814        public String toString() {
1815            return ISODateTimeFormat.date().print(this);
1816        }
1817    
1818        /**
1819         * Output the date using the specified format pattern.
1820         *
1821         * @param pattern  the pattern specification, null means use <code>toString</code>
1822         * @see org.joda.time.format.DateTimeFormat
1823         */
1824        public String toString(String pattern) {
1825            if (pattern == null) {
1826                return toString();
1827            }
1828            return DateTimeFormat.forPattern(pattern).print(this);
1829        }
1830    
1831        /**
1832         * Output the date using the specified format pattern.
1833         *
1834         * @param pattern  the pattern specification, null means use <code>toString</code>
1835         * @param locale  Locale to use, null means default
1836         * @see org.joda.time.format.DateTimeFormat
1837         */
1838        public String toString(String pattern, Locale locale) throws IllegalArgumentException {
1839            if (pattern == null) {
1840                return toString();
1841            }
1842            return DateTimeFormat.forPattern(pattern).withLocale(locale).print(this);
1843        }
1844    
1845        //-----------------------------------------------------------------------
1846        /**
1847         * LocalDate.Property binds a LocalDate to a DateTimeField allowing
1848         * powerful datetime functionality to be easily accessed.
1849         * <p>
1850         * The simplest use of this class is as an alternative get method, here used to
1851         * get the year '1972' (as an int) and the month 'December' (as a String).
1852         * <pre>
1853         * LocalDate dt = new LocalDate(1972, 12, 3, 0, 0);
1854         * int year = dt.year().get();
1855         * String monthStr = dt.month().getAsText();
1856         * </pre>
1857         * <p>
1858         * Methods are also provided that allow date modification. These return
1859         * new instances of LocalDate - they do not modify the original. The example
1860         * below yields two independent immutable date objects 20 years apart.
1861         * <pre>
1862         * LocalDate dt = new LocalDate(1972, 12, 3);
1863         * LocalDate dt1920 = dt.year().setCopy(1920);
1864         * </pre>
1865         * <p>
1866         * LocalDate.Property itself is thread-safe and immutable, as well as the
1867         * LocalDate being operated on.
1868         *
1869         * @author Stephen Colebourne
1870         * @author Brian S O'Neill
1871         * @since 1.3
1872         */
1873        public static final class Property extends AbstractReadableInstantFieldProperty {
1874            
1875            /** Serialization version */
1876            private static final long serialVersionUID = -3193829732634L;
1877            
1878            /** The instant this property is working against */
1879            private transient LocalDate iInstant;
1880            /** The field this property is working against */
1881            private transient DateTimeField iField;
1882            
1883            /**
1884             * Constructor.
1885             * 
1886             * @param instant  the instant to set
1887             * @param field  the field to use
1888             */
1889            Property(LocalDate instant, DateTimeField field) {
1890                super();
1891                iInstant = instant;
1892                iField = field;
1893            }
1894            
1895            /**
1896             * Writes the property in a safe serialization format.
1897             */
1898            private void writeObject(ObjectOutputStream oos) throws IOException {
1899                oos.writeObject(iInstant);
1900                oos.writeObject(iField.getType());
1901            }
1902    
1903            /**
1904             * Reads the property from a safe serialization format.
1905             */
1906            private void readObject(ObjectInputStream oos) throws IOException, ClassNotFoundException {
1907                iInstant = (LocalDate) oos.readObject();
1908                DateTimeFieldType type = (DateTimeFieldType) oos.readObject();
1909                iField = type.getField(iInstant.getChronology());
1910            }
1911    
1912            //-----------------------------------------------------------------------
1913            /**
1914             * Gets the field being used.
1915             * 
1916             * @return the field
1917             */
1918            public DateTimeField getField() {
1919                return iField;
1920            }
1921            
1922            /**
1923             * Gets the milliseconds of the date that this property is linked to.
1924             * 
1925             * @return the milliseconds
1926             */
1927            protected long getMillis() {
1928                return iInstant.getLocalMillis();
1929            }
1930            
1931            /**
1932             * Gets the chronology of the datetime that this property is linked to.
1933             * 
1934             * @return the chronology
1935             * @since 1.4
1936             */
1937            protected Chronology getChronology() {
1938                return iInstant.getChronology();
1939            }
1940            
1941            /**
1942             * Gets the LocalDate object linked to this property.
1943             * 
1944             * @return the linked LocalDate
1945             */
1946            public LocalDate getLocalDate() {
1947                return iInstant;
1948            }
1949            
1950            //-----------------------------------------------------------------------
1951            /**
1952             * Adds to this field in a copy of this LocalDate.
1953             * <p>
1954             * The LocalDate attached to this property is unchanged by this call.
1955             *
1956             * @param value  the value to add to the field in the copy
1957             * @return a copy of the LocalDate with the field value changed
1958             * @throws IllegalArgumentException if the value isn't valid
1959             */
1960            public LocalDate addToCopy(int value) {
1961                return iInstant.withLocalMillis(iField.add(iInstant.getLocalMillis(), value));
1962            }
1963            
1964            /**
1965             * Adds to this field, possibly wrapped, in a copy of this LocalDate.
1966             * A field wrapped operation only changes this field.
1967             * Thus 31st January addWrapField one day goes to the 1st January.
1968             * <p>
1969             * The LocalDate attached to this property is unchanged by this call.
1970             *
1971             * @param value  the value to add to the field in the copy
1972             * @return a copy of the LocalDate with the field value changed
1973             * @throws IllegalArgumentException if the value isn't valid
1974             */
1975            public LocalDate addWrapFieldToCopy(int value) {
1976                return iInstant.withLocalMillis(iField.addWrapField(iInstant.getLocalMillis(), value));
1977            }
1978            
1979            //-----------------------------------------------------------------------
1980            /**
1981             * Sets this field in a copy of the LocalDate.
1982             * <p>
1983             * The LocalDate attached to this property is unchanged by this call.
1984             *
1985             * @param value  the value to set the field in the copy to
1986             * @return a copy of the LocalDate with the field value changed
1987             * @throws IllegalArgumentException if the value isn't valid
1988             */
1989            public LocalDate setCopy(int value) {
1990                return iInstant.withLocalMillis(iField.set(iInstant.getLocalMillis(), value));
1991            }
1992            
1993            /**
1994             * Sets this field in a copy of the LocalDate to a parsed text value.
1995             * <p>
1996             * The LocalDate attached to this property is unchanged by this call.
1997             *
1998             * @param text  the text value to set
1999             * @param locale  optional locale to use for selecting a text symbol
2000             * @return a copy of the LocalDate with the field value changed
2001             * @throws IllegalArgumentException if the text value isn't valid
2002             */
2003            public LocalDate setCopy(String text, Locale locale) {
2004                return iInstant.withLocalMillis(iField.set(iInstant.getLocalMillis(), text, locale));
2005            }
2006            
2007            /**
2008             * Sets this field in a copy of the LocalDate to a parsed text value.
2009             * <p>
2010             * The LocalDate attached to this property is unchanged by this call.
2011             *
2012             * @param text  the text value to set
2013             * @return a copy of the LocalDate with the field value changed
2014             * @throws IllegalArgumentException if the text value isn't valid
2015             */
2016            public LocalDate setCopy(String text) {
2017                return setCopy(text, null);
2018            }
2019            
2020            //-----------------------------------------------------------------------
2021            /**
2022             * Returns a new LocalDate with this field set to the maximum value
2023             * for this field.
2024             * <p>
2025             * This operation is useful for obtaining a LocalDate on the last day
2026             * of the month, as month lengths vary.
2027             * <pre>
2028             * LocalDate lastDayOfMonth = dt.dayOfMonth().withMaximumValue();
2029             * </pre>
2030             * <p>
2031             * The LocalDate attached to this property is unchanged by this call.
2032             *
2033             * @return a copy of the LocalDate with this field set to its maximum
2034             */
2035            public LocalDate withMaximumValue() {
2036                return setCopy(getMaximumValue());
2037            }
2038            
2039            /**
2040             * Returns a new LocalDate with this field set to the minimum value
2041             * for this field.
2042             * <p>
2043             * The LocalDate attached to this property is unchanged by this call.
2044             *
2045             * @return a copy of the LocalDate with this field set to its minimum
2046             */
2047            public LocalDate withMinimumValue() {
2048                return setCopy(getMinimumValue());
2049            }
2050            
2051            //-----------------------------------------------------------------------
2052            /**
2053             * Rounds to the lowest whole unit of this field on a copy of this
2054             * LocalDate.
2055             * <p>
2056             * For example, rounding floor on the hourOfDay field of a LocalDate
2057             * where the time is 10:30 would result in new LocalDate with the
2058             * time of 10:00.
2059             *
2060             * @return a copy of the LocalDate with the field value changed
2061             */
2062            public LocalDate roundFloorCopy() {
2063                return iInstant.withLocalMillis(iField.roundFloor(iInstant.getLocalMillis()));
2064            }
2065            
2066            /**
2067             * Rounds to the highest whole unit of this field on a copy of this
2068             * LocalDate.
2069             * <p>
2070             * For example, rounding floor on the hourOfDay field of a LocalDate
2071             * where the time is 10:30 would result in new LocalDate with the
2072             * time of 11:00.
2073             *
2074             * @return a copy of the LocalDate with the field value changed
2075             */
2076            public LocalDate roundCeilingCopy() {
2077                return iInstant.withLocalMillis(iField.roundCeiling(iInstant.getLocalMillis()));
2078            }
2079            
2080            /**
2081             * Rounds to the nearest whole unit of this field on a copy of this
2082             * LocalDate, favoring the floor if halfway.
2083             *
2084             * @return a copy of the LocalDate with the field value changed
2085             */
2086            public LocalDate roundHalfFloorCopy() {
2087                return iInstant.withLocalMillis(iField.roundHalfFloor(iInstant.getLocalMillis()));
2088            }
2089            
2090            /**
2091             * Rounds to the nearest whole unit of this field on a copy of this
2092             * LocalDate, favoring the ceiling if halfway.
2093             *
2094             * @return a copy of the LocalDate with the field value changed
2095             */
2096            public LocalDate roundHalfCeilingCopy() {
2097                return iInstant.withLocalMillis(iField.roundHalfCeiling(iInstant.getLocalMillis()));
2098            }
2099            
2100            /**
2101             * Rounds to the nearest whole unit of this field on a copy of this
2102             * LocalDate.  If halfway, the ceiling is favored over the floor
2103             * only if it makes this field's value even.
2104             *
2105             * @return a copy of the LocalDate with the field value changed
2106             */
2107            public LocalDate roundHalfEvenCopy() {
2108                return iInstant.withLocalMillis(iField.roundHalfEven(iInstant.getLocalMillis()));
2109            }
2110        }
2111    
2112    }