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