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 (iChronology == null) {
455                return new LocalDate(iLocalMillis, ISOChronology.getInstanceUTC());
456            }
457            if (DateTimeZone.UTC.equals(iChronology.getZone()) == false) {
458                return new LocalDate(iLocalMillis, iChronology.withUTC());
459            }
460            return this;
461        }
462    
463        //-----------------------------------------------------------------------
464        /**
465         * Gets the number of fields in this partial, which is three.
466         * The supported fields are Year, MonthOfYear and DayOfMonth.
467         * Note that all fields from day and above may in fact be queried via
468         * other methods.
469         *
470         * @return the field count, three
471         */
472        public int size() {
473            return 3;
474        }
475    
476        /**
477         * Gets the field for a specific index in the chronology specified.
478         * <p>
479         * This method must not use any instance variables.
480         *
481         * @param index  the index to retrieve
482         * @param chrono  the chronology to use
483         * @return the field
484         */
485        protected DateTimeField getField(int index, Chronology chrono) {
486            switch (index) {
487                case YEAR:
488                    return chrono.year();
489                case MONTH_OF_YEAR:
490                    return chrono.monthOfYear();
491                case DAY_OF_MONTH:
492                    return chrono.dayOfMonth();
493                default:
494                    throw new IndexOutOfBoundsException("Invalid index: " + index);
495            }
496        }
497    
498        /**
499         * Gets the value of the field at the specifed index.
500         * <p>
501         * This method is required to support the <code>ReadablePartial</code>
502         * interface. The supported fields are Year, MonthOfYear and DayOfMonth.
503         * Note that all fields from day and above may in fact be queried via
504         * other methods.
505         *
506         * @param index  the index, zero to two
507         * @return the value
508         * @throws IndexOutOfBoundsException if the index is invalid
509         */
510        public int getValue(int index) {
511            switch (index) {
512                case YEAR:
513                    return getChronology().year().get(getLocalMillis());
514                case MONTH_OF_YEAR:
515                    return getChronology().monthOfYear().get(getLocalMillis());
516                case DAY_OF_MONTH:
517                    return getChronology().dayOfMonth().get(getLocalMillis());
518                default:
519                    throw new IndexOutOfBoundsException("Invalid index: " + index);
520            }
521        }
522    
523        //-----------------------------------------------------------------------
524        /**
525         * Get the value of one of the fields of a datetime.
526         * <p>
527         * This method gets the value of the specified field.
528         * For example:
529         * <pre>
530         * LocalDate dt = LocalDate.nowDefaultZone();
531         * int year = dt.get(DateTimeFieldType.year());
532         * </pre>
533         *
534         * @param fieldType  a field type, usually obtained from DateTimeFieldType, not null
535         * @return the value of that field
536         * @throws IllegalArgumentException if the field type is null or unsupported
537         */
538        public int get(DateTimeFieldType fieldType) {
539            if (fieldType == null) {
540                throw new IllegalArgumentException("The DateTimeFieldType must not be null");
541            }
542            if (isSupported(fieldType) == false) {
543                throw new IllegalArgumentException("Field '" + fieldType + "' is not supported");
544            }
545            return fieldType.getField(getChronology()).get(getLocalMillis());
546        }
547    
548        /**
549         * Checks if the field type specified is supported by this
550         * local date and chronology.
551         * This can be used to avoid exceptions in {@link #get(DateTimeFieldType)}.
552         *
553         * @param type  a field type, usually obtained from DateTimeFieldType
554         * @return true if the field type is supported
555         */
556        public boolean isSupported(DateTimeFieldType type) {
557            if (type == null) {
558                return false;
559            }
560            DurationFieldType durType = type.getDurationType();
561            if (DATE_DURATION_TYPES.contains(durType) ||
562                    durType.getField(getChronology()).getUnitMillis() >=
563                        getChronology().days().getUnitMillis()) {
564                return type.getField(getChronology()).isSupported();
565            }
566            return false;
567        }
568    
569        /**
570         * Checks if the duration type specified is supported by this
571         * local date and chronology.
572         *
573         * @param type  a duration type, usually obtained from DurationFieldType
574         * @return true if the field type is supported
575         */
576        public boolean isSupported(DurationFieldType type) {
577            if (type == null) {
578                return false;
579            }
580            DurationField field = type.getField(getChronology());
581            if (DATE_DURATION_TYPES.contains(type) ||
582                field.getUnitMillis() >= getChronology().days().getUnitMillis()) {
583                return field.isSupported();
584            }
585            return false;
586        }
587    
588        //-----------------------------------------------------------------------
589        /**
590         * Gets the local milliseconds from the Java epoch
591         * of 1970-01-01T00:00:00 (not fixed to any specific time zone).
592         * 
593         * @return the number of milliseconds since 1970-01-01T00:00:00
594         * @since 1.5 (previously private)
595         */
596        protected long getLocalMillis() {
597            return iLocalMillis;
598        }
599    
600        /**
601         * Gets the chronology of the date.
602         * 
603         * @return the Chronology that the date is using
604         */
605        public Chronology getChronology() {
606            return iChronology;
607        }
608    
609        //-----------------------------------------------------------------------
610        /**
611         * Compares this ReadablePartial with another returning true if the chronology,
612         * field types and values are equal.
613         *
614         * @param partial  an object to check against
615         * @return true if fields and values are equal
616         */
617        public boolean equals(Object partial) {
618            // override to perform faster
619            if (this == partial) {
620                return true;
621            }
622            if (partial instanceof LocalDate) {
623                LocalDate other = (LocalDate) partial;
624                if (iChronology.equals(other.iChronology)) {
625                    return iLocalMillis == other.iLocalMillis;
626                }
627            }
628            return super.equals(partial);
629        }
630    
631        /**
632         * Gets a hash code for the instant as defined in <code>ReadablePartial</code>.
633         *
634         * @return a suitable hash code
635         */
636        public int hashCode() {
637            // override for performance
638            int hash = iHash;
639            if (hash == 0) {
640                hash = iHash = super.hashCode();
641            }
642            return hash;
643        }
644    
645        /**
646         * Compares this partial with another returning an integer
647         * indicating the order.
648         * <p>
649         * The fields are compared in order, from largest to smallest.
650         * The first field that is non-equal is used to determine the result.
651         * <p>
652         * The specified object must be a partial instance whose field types
653         * match those of this partial.
654         *
655         * @param partial  an object to check against
656         * @return negative if this is less, zero if equal, positive if greater
657         * @throws ClassCastException if the partial is the wrong class
658         *  or if it has field types that don't match
659         * @throws NullPointerException if the partial is null
660         */
661        public int compareTo(ReadablePartial partial) {
662            // override to perform faster
663            if (this == partial) {
664                return 0;
665            }
666            if (partial instanceof LocalDate) {
667                LocalDate other = (LocalDate) partial;
668                if (iChronology.equals(other.iChronology)) {
669                    return (iLocalMillis < other.iLocalMillis ? -1 :
670                                (iLocalMillis == other.iLocalMillis ? 0 : 1));
671    
672                }
673            }
674            return super.compareTo(partial);
675        }
676    
677        //-----------------------------------------------------------------------
678        /**
679         * Converts this LocalDate to a full datetime at the earliest valid time
680         * for the date using the default time zone.
681         * <p>
682         * The time will normally be midnight, as that is the earliest time on
683         * any given day. However, in some time zones when Daylight Savings Time
684         * starts, there is no midnight because time jumps from 11:59 to 01:00.
685         * This method handles that situation by returning 01:00 on that date.
686         * <p>
687         * This instance is immutable and unaffected by this method call.
688         * 
689         * @return this date as a datetime at the start of the day
690         * @since 1.5
691         */
692        public DateTime toDateTimeAtStartOfDay() {
693            return toDateTimeAtStartOfDay(null);
694        }
695    
696        /**
697         * Converts this LocalDate to a full datetime at the earliest valid time
698         * for the date using the specified time zone.
699         * <p>
700         * The time will normally be midnight, as that is the earliest time on
701         * any given day. However, in some time zones when Daylight Savings Time
702         * starts, there is no midnight because time jumps from 11:59 to 01:00.
703         * This method handles that situation by returning 01:00 on that date.
704         * <p>
705         * This method uses the chronology from this instance plus the time zone
706         * specified.
707         * <p>
708         * This instance is immutable and unaffected by this method call.
709         *
710         * @param zone  the zone to use, null means default zone
711         * @return this date as a datetime at the start of the day
712         * @since 1.5
713         */
714        public DateTime toDateTimeAtStartOfDay(DateTimeZone zone) {
715            zone = DateTimeUtils.getZone(zone);
716            Chronology chrono = getChronology().withZone(zone);
717            long localMillis = getLocalMillis() + 6L * DateTimeConstants.MILLIS_PER_HOUR;
718            long instant = zone.convertLocalToUTC(localMillis, false);
719            instant = chrono.dayOfMonth().roundFloor(instant);
720            return new DateTime(instant, chrono);
721        }
722    
723        //-----------------------------------------------------------------------
724        /**
725         * Converts this LocalDate to a full datetime at midnight using the default
726         * time zone.
727         * <p>
728         * This method will throw an exception if the default time zone switches
729         * to Daylight Savings Time at midnight and this LocalDate represents
730         * that switchover date. The problem is that there is no such time as
731         * midnight on the required date, and as such an exception is thrown.
732         * <p>
733         * This instance is immutable and unaffected by this method call.
734         * 
735         * @return this date as a datetime at midnight
736         * @deprecated Use {@link #toDateTimeAtStartOfDay()} which won't throw an exception
737         */
738        @Deprecated
739        public DateTime toDateTimeAtMidnight() {
740            return toDateTimeAtMidnight(null);
741        }
742    
743        /**
744         * Converts this LocalDate to a full datetime at midnight using the
745         * specified time zone.
746         * <p>
747         * This method will throw an exception if the time zone switches
748         * to Daylight Savings Time at midnight and this LocalDate represents
749         * that switchover date. The problem is that there is no such time as
750         * midnight on the required date, and as such an exception is thrown.
751         * <p>
752         * This method uses the chronology from this instance plus the time zone
753         * specified.
754         * <p>
755         * This instance is immutable and unaffected by this method call.
756         *
757         * @param zone  the zone to use, null means default zone
758         * @return this date as a datetime at midnight
759         * @deprecated Use {@link #toDateTimeAtStartOfDay(DateTimeZone)} which won't throw an exception
760         */
761        @Deprecated
762        public DateTime toDateTimeAtMidnight(DateTimeZone zone) {
763            zone = DateTimeUtils.getZone(zone);
764            Chronology chrono = getChronology().withZone(zone);
765            return new DateTime(getYear(), getMonthOfYear(), getDayOfMonth(), 0, 0, 0, 0, chrono);
766        }
767    
768        //-----------------------------------------------------------------------
769        /**
770         * Converts this LocalDate to a full datetime using the default time zone
771         * setting the date fields from this instance and the time fields from
772         * the current time.
773         * <p>
774         * This method will throw an exception if the datetime that would be
775         * created does not exist when the time zone is taken into account.
776         * <p>
777         * This instance is immutable and unaffected by this method call.
778         *
779         * @return this date as a datetime with the time as the current time
780         */
781        public DateTime toDateTimeAtCurrentTime() {
782            return toDateTimeAtCurrentTime(null);
783        }
784    
785        /**
786         * Converts this LocalDate to a full datetime using the specified time zone
787         * setting the date fields from this instance and the time fields from
788         * the current time.
789         * <p>
790         * This method uses the chronology from this instance plus the time zone
791         * specified.
792         * <p>
793         * This method will throw an exception if the datetime that would be
794         * created does not exist when the time zone is taken into account.
795         * <p>
796         * This instance is immutable and unaffected by this method call.
797         *
798         * @param zone  the zone to use, null means default zone
799         * @return this date as a datetime with the time as the current time
800         */
801        public DateTime toDateTimeAtCurrentTime(DateTimeZone zone) {
802            zone = DateTimeUtils.getZone(zone);
803            Chronology chrono = getChronology().withZone(zone);
804            long instantMillis = DateTimeUtils.currentTimeMillis();
805            long resolved = chrono.set(this, instantMillis);
806            return new DateTime(resolved, chrono);
807        }
808    
809        //-----------------------------------------------------------------------
810        /**
811         * Converts this LocalDate to a DateMidnight in the default time zone.
812         * <p>
813         * As from v1.5, you are recommended to avoid DateMidnight and use
814         * {@link #toDateTimeAtStartOfDay()} instead because of the exception
815         * detailed below.
816         * <p>
817         * This method will throw an exception if the default time zone switches
818         * to Daylight Savings Time at midnight and this LocalDate represents
819         * that switchover date. The problem is that there is no such time as
820         * midnight on the required date, and as such an exception is thrown.
821         * <p>
822         * This instance is immutable and unaffected by this method call.
823         *
824         * @return the DateMidnight instance in the default zone
825         */
826        public DateMidnight toDateMidnight() {
827            return toDateMidnight(null);
828        }
829    
830        /**
831         * Converts this LocalDate to a DateMidnight.
832         * <p>
833         * As from v1.5, you are recommended to avoid DateMidnight and use
834         * {@link #toDateTimeAtStartOfDay()} instead because of the exception
835         * detailed below.
836         * <p>
837         * This method will throw an exception if the time zone switches
838         * to Daylight Savings Time at midnight and this LocalDate represents
839         * that switchover date. The problem is that there is no such time as
840         * midnight on the required date, and as such an exception is thrown.
841         * <p>
842         * This instance is immutable and unaffected by this method call.
843         *
844         * @param zone  the zone to get the DateMidnight in, null means default zone
845         * @return the DateMidnight instance
846         */
847        public DateMidnight toDateMidnight(DateTimeZone zone) {
848            zone = DateTimeUtils.getZone(zone);
849            Chronology chrono = getChronology().withZone(zone);
850            return new DateMidnight(getYear(), getMonthOfYear(), getDayOfMonth(), chrono);
851        }
852    
853        //-----------------------------------------------------------------------
854        /**
855         * Converts this object to a LocalDateTime using a LocalTime to fill in
856         * the missing fields.
857         * <p>
858         * The resulting chronology is determined by the chronology of this
859         * LocalDate. The chronology of the time must also match.
860         * If the time is null an exception is thrown.
861         * <p>
862         * This instance is immutable and unaffected by this method call.
863         *
864         * @param time  the time of day to use, must not be null
865         * @return the LocalDateTime instance
866         * @throws IllegalArgumentException if the time is null
867         * @throws IllegalArgumentException if the chronology of the time does not match
868         * @since 1.5
869         */
870        public LocalDateTime toLocalDateTime(LocalTime time) {
871            if (time == null) {
872                throw new IllegalArgumentException("The time must not be null");
873            }
874            if (getChronology() != time.getChronology()) {
875                throw new IllegalArgumentException("The chronology of the time does not match");
876            }
877            long localMillis = getLocalMillis() + time.getLocalMillis();
878            return new LocalDateTime(localMillis, getChronology());
879        }
880    
881        //-----------------------------------------------------------------------
882        /**
883         * Converts this object to a DateTime using a LocalTime to fill in the
884         * missing fields and using the default time zone.
885         * <p>
886         * The resulting chronology is determined by the chronology of this
887         * LocalDate. The chronology of the time must match.
888         * If the time is null, the current time in the date's chronology is used.
889         * <p>
890         * This method will throw an exception if the datetime that would be
891         * created does not exist when the time zone is taken into account.
892         * <p>
893         * This instance is immutable and unaffected by this method call.
894         *
895         * @param time  the time of day to use, null means current time
896         * @return the DateTime instance
897         * @throws IllegalArgumentException if the chronology of the time does not match
898         */
899        public DateTime toDateTime(LocalTime time) {
900            return toDateTime(time, null);
901        }
902    
903        /**
904         * Converts this object to a DateTime using a LocalTime to fill in the
905         * missing fields.
906         * <p>
907         * The resulting chronology is determined by the chronology of this
908         * LocalDate plus the time zone. The chronology of the time must match.
909         * If the time is null, the current time in the date's chronology is used.
910         * <p>
911         * This method will throw an exception if the datetime that would be
912         * created does not exist when the time zone is taken into account.
913         * <p>
914         * This instance is immutable and unaffected by this method call.
915         *
916         * @param time  the time of day to use, null means current time
917         * @param zone  the zone to get the DateTime in, null means default
918         * @return the DateTime instance
919         * @throws IllegalArgumentException if the chronology of the time does not match
920         */
921        public DateTime toDateTime(LocalTime time, DateTimeZone zone) {
922            if (time != null && getChronology() != time.getChronology()) {
923                throw new IllegalArgumentException("The chronology of the time does not match");
924            }
925            Chronology chrono = getChronology().withZone(zone);
926            long instant = DateTimeUtils.currentTimeMillis();
927            instant = chrono.set(this, instant);
928            if (time != null) {
929                instant = chrono.set(time, instant);
930            }
931            return new DateTime(instant, chrono);
932        }
933    
934        //-----------------------------------------------------------------------
935        /**
936         * Converts this object to an Interval representing the whole day
937         * in the default time zone.
938         * <p>
939         * The interval may have more or less than 24 hours if this is a daylight
940         * savings cutover date.
941         * <p>
942         * This instance is immutable and unaffected by this method call.
943         *
944         * @return a interval over the day
945         */
946        public Interval toInterval() {
947            return toInterval(null);
948        }
949    
950        /**
951         * Converts this object to an Interval representing the whole day.
952         * <p>
953         * The interval may have more or less than 24 hours if this is a daylight
954         * savings cutover date.
955         * <p>
956         * This instance is immutable and unaffected by this method call.
957         *
958         * @param zone  the zone to get the Interval in, null means default
959         * @return a interval over the day
960         */
961        public Interval toInterval(DateTimeZone zone) {
962            zone = DateTimeUtils.getZone(zone);
963            DateTime start = toDateTimeAtStartOfDay(zone);
964            DateTime end = plusDays(1).toDateTimeAtStartOfDay(zone);
965            return new Interval(start, end);
966        }
967    
968        //-----------------------------------------------------------------------
969        /**
970         * Get the date time as a <code>java.util.Date</code>.
971         * <p>
972         * The <code>Date</code> object created has exactly the same year, month and day
973         * as this date. The time will be set to the earliest valid time for that date.
974         * <p>
975         * Converting to a JDK Date is full of complications as the JDK Date constructor
976         * doesn't behave as you might expect around DST transitions. This method works
977         * by taking a first guess and then adjusting the JDK date until it has the
978         * earliest valid instant. This also handles the situation where the JDK time
979         * zone data differs from the Joda-Time time zone data.
980         *
981         * @return a Date initialised with this date, never null
982         * @since 2.0
983         */
984        @SuppressWarnings("deprecation")
985        public Date toDate() {
986            int dom = getDayOfMonth();
987            Date date = new Date(getYear() - 1900, getMonthOfYear() - 1, dom);
988            LocalDate check = LocalDate.fromDateFields(date);
989            if (check.isBefore(this)) {
990                // DST gap (no midnight)
991                // move forward in units of one hour until date correct
992                while (check.equals(this) == false) {
993                    date.setTime(date.getTime() + 3600000);
994                    check = LocalDate.fromDateFields(date);
995                }
996                // move back in units of one second until date wrong
997                while (date.getDate() == dom) {
998                    date.setTime(date.getTime() - 1000);
999                }
1000                // fix result
1001                date.setTime(date.getTime() + 1000);
1002            } else if (check.equals(this)) {
1003                // check for DST overlap (two midnights)
1004                Date earlier = new Date(date.getTime() - TimeZone.getDefault().getDSTSavings());
1005                if (earlier.getDate() == dom) {
1006                    date = earlier;
1007                }
1008            }
1009            return date;
1010        }
1011    
1012        //-----------------------------------------------------------------------
1013        /**
1014         * Returns a copy of this date with different local millis.
1015         * <p>
1016         * The returned object will be a new instance of the same type.
1017         * Only the millis will change, the chronology is kept.
1018         * The returned object will be either be a new instance or <code>this</code>.
1019         *
1020         * @param newMillis  the new millis, from 1970-01-01T00:00:00
1021         * @return a copy of this date with different millis
1022         */
1023        LocalDate withLocalMillis(long newMillis) {
1024            newMillis = iChronology.dayOfMonth().roundFloor(newMillis);
1025            return (newMillis == getLocalMillis() ? this : new LocalDate(newMillis, getChronology()));
1026        }
1027    
1028        //-----------------------------------------------------------------------
1029        /**
1030         * Returns a copy of this date with the partial set of fields replacing
1031         * those from this instance.
1032         * <p>
1033         * For example, if the partial contains a year and a month then those two
1034         * fields will be changed in the returned instance.
1035         * Unsupported fields are ignored.
1036         * If the partial is null, then <code>this</code> is returned.
1037         *
1038         * @param partial  the partial set of fields to apply to this date, null ignored
1039         * @return a copy of this date with a different set of fields
1040         * @throws IllegalArgumentException if any value is invalid
1041         */
1042        public LocalDate withFields(ReadablePartial partial) {
1043            if (partial == null) {
1044                return this;
1045            }
1046            return withLocalMillis(getChronology().set(partial, getLocalMillis()));
1047        }
1048    
1049        /**
1050         * Returns a copy of this date with the specified field set to a new value.
1051         * <p>
1052         * For example, if the field type is <code>monthOfYear</code> then the
1053         * month of year field will be changed in the returned instance.
1054         * If the field type is null, then <code>this</code> is returned.
1055         * <p>
1056         * These two lines are equivalent:
1057         * <pre>
1058         * LocalDate updated = dt.withDayOfMonth(6);
1059         * LocalDate updated = dt.withField(DateTimeFieldType.dayOfMonth(), 6);
1060         * </pre>
1061         *
1062         * @param fieldType  the field type to set, not null
1063         * @param value  the value to set
1064         * @return a copy of this date with the field set
1065         * @throws IllegalArgumentException if the field is null or unsupported
1066         */
1067        public LocalDate withField(DateTimeFieldType fieldType, int value) {
1068            if (fieldType == null) {
1069                throw new IllegalArgumentException("Field must not be null");
1070            }
1071            if (isSupported(fieldType) == false) {
1072                throw new IllegalArgumentException("Field '" + fieldType + "' is not supported");
1073            }
1074            long instant = fieldType.getField(getChronology()).set(getLocalMillis(), value);
1075            return withLocalMillis(instant);
1076        }
1077    
1078        /**
1079         * Returns a copy of this date with the value of the specified field increased.
1080         * <p>
1081         * If the addition is zero or the field is null, then <code>this</code> is returned.
1082         * <p>
1083         * These three lines are equivalent:
1084         * <pre>
1085         * LocalDate added = dt.withFieldAdded(DurationFieldType.years(), 6);
1086         * LocalDate added = dt.plusYears(6);
1087         * LocalDate added = dt.plus(Period.years(6));
1088         * </pre>
1089         *
1090         * @param fieldType  the field type to add to, not null
1091         * @param amount  the amount to add
1092         * @return a copy of this date with the field updated
1093         * @throws IllegalArgumentException if the field is null or unsupported
1094         * @throws ArithmeticException if the result exceeds the internal capacity
1095         */
1096        public LocalDate withFieldAdded(DurationFieldType fieldType, int amount) {
1097            if (fieldType == null) {
1098                throw new IllegalArgumentException("Field must not be null");
1099            }
1100            if (isSupported(fieldType) == false) {
1101                throw new IllegalArgumentException("Field '" + fieldType + "' is not supported");
1102            }
1103            if (amount == 0) {
1104                return this;
1105            }
1106            long instant = fieldType.getField(getChronology()).add(getLocalMillis(), amount);
1107            return withLocalMillis(instant);
1108        }
1109    
1110        //-----------------------------------------------------------------------
1111        /**
1112         * Returns a copy of this date with the specified period added.
1113         * <p>
1114         * If the addition is zero, then <code>this</code> is returned.
1115         * <p>
1116         * This method is typically used to add multiple copies of complex
1117         * period instances. Adding one field is best achieved using methods
1118         * like {@link #withFieldAdded(DurationFieldType, int)}
1119         * or {@link #plusYears(int)}.
1120         * <p>
1121         * Unsupported time fields are ignored, thus adding a period of 24 hours
1122         * will not have any effect.
1123         *
1124         * @param period  the period to add to this one, null means zero
1125         * @param scalar  the amount of times to add, such as -1 to subtract once
1126         * @return a copy of this date with the period added
1127         * @throws ArithmeticException if the result exceeds the internal capacity
1128         */
1129        public LocalDate withPeriodAdded(ReadablePeriod period, int scalar) {
1130            if (period == null || scalar == 0) {
1131                return this;
1132            }
1133            long instant = getLocalMillis();
1134            Chronology chrono = getChronology();
1135            for (int i = 0; i < period.size(); i++) {
1136                long value = FieldUtils.safeMultiply(period.getValue(i), scalar);
1137                DurationFieldType type = period.getFieldType(i);
1138                if (isSupported(type)) {
1139                    instant = type.getField(chrono).add(instant, value);
1140                }
1141            }
1142            return withLocalMillis(instant);
1143        }
1144    
1145        //-----------------------------------------------------------------------
1146        /**
1147         * Returns a copy of this date with the specified period added.
1148         * <p>
1149         * If the amount is zero or null, then <code>this</code> is returned.
1150         * <p>
1151         * This method is typically used to add complex period instances.
1152         * Adding one field is best achieved using methods
1153         * like {@link #plusYears(int)}.
1154         * <p>
1155         * Unsupported time fields are ignored, thus adding a period of 24 hours
1156         * will not have any effect.
1157         *
1158         * @param period  the period to add to this one, null means zero
1159         * @return a copy of this date with the period added
1160         * @throws ArithmeticException if the result exceeds the internal capacity
1161         */
1162        public LocalDate plus(ReadablePeriod period) {
1163            return withPeriodAdded(period, 1);
1164        }
1165    
1166        //-----------------------------------------------------------------------
1167        /**
1168         * Returns a copy of this date plus the specified number of years.
1169         * <p>
1170         * This adds the specified number of years to the date.
1171         * If adding years makes the day-of-month invalid, it is adjusted to the last valid day in the month.
1172         * This LocalDate instance is immutable and unaffected by this method call.
1173         * <p>
1174         * The following three lines are identical in effect:
1175         * <pre>
1176         * LocalDate added = dt.plusYears(6);
1177         * LocalDate added = dt.plus(Period.years(6));
1178         * LocalDate added = dt.withFieldAdded(DurationFieldType.years(), 6);
1179         * </pre>
1180         *
1181         * @param years  the amount of years to add, may be negative
1182         * @return the new LocalDate plus the increased years
1183         */
1184        public LocalDate plusYears(int years) {
1185            if (years == 0) {
1186                return this;
1187            }
1188            long instant = getChronology().years().add(getLocalMillis(), years);
1189            return withLocalMillis(instant);
1190        }
1191    
1192        /**
1193         * Returns a copy of this date plus the specified number of months.
1194         * <p>
1195         * This adds the specified number of months to the date.
1196         * The addition may change the year, but the day-of-month is normally unchanged.
1197         * If adding months makes the day-of-month invalid, it is adjusted to the last valid day in the month.
1198         * This LocalDate instance is immutable and unaffected by this method call.
1199         * <p>
1200         * The following three lines are identical in effect:
1201         * <pre>
1202         * LocalDate added = dt.plusMonths(6);
1203         * LocalDate added = dt.plus(Period.months(6));
1204         * LocalDate added = dt.withFieldAdded(DurationFieldType.months(), 6);
1205         * </pre>
1206         *
1207         * @param months  the amount of months to add, may be negative
1208         * @return the new LocalDate plus the increased months
1209         */
1210        public LocalDate plusMonths(int months) {
1211            if (months == 0) {
1212                return this;
1213            }
1214            long instant = getChronology().months().add(getLocalMillis(), months);
1215            return withLocalMillis(instant);
1216        }
1217    
1218        /**
1219         * Returns a copy of this date plus the specified number of weeks.
1220         * <p>
1221         * This LocalDate instance is immutable and unaffected by this method call.
1222         * <p>
1223         * The following three lines are identical in effect:
1224         * <pre>
1225         * LocalDate added = dt.plusWeeks(6);
1226         * LocalDate added = dt.plus(Period.weeks(6));
1227         * LocalDate added = dt.withFieldAdded(DurationFieldType.weeks(), 6);
1228         * </pre>
1229         *
1230         * @param weeks  the amount of weeks to add, may be negative
1231         * @return the new LocalDate plus the increased weeks
1232         */
1233        public LocalDate plusWeeks(int weeks) {
1234            if (weeks == 0) {
1235                return this;
1236            }
1237            long instant = getChronology().weeks().add(getLocalMillis(), weeks);
1238            return withLocalMillis(instant);
1239        }
1240    
1241        /**
1242         * Returns a copy of this date plus the specified number of days.
1243         * <p>
1244         * This LocalDate instance is immutable and unaffected by this method call.
1245         * <p>
1246         * The following three lines are identical in effect:
1247         * <pre>
1248         * LocalDate added = dt.plusDays(6);
1249         * LocalDate added = dt.plus(Period.days(6));
1250         * LocalDate added = dt.withFieldAdded(DurationFieldType.days(), 6);
1251         * </pre>
1252         *
1253         * @param days  the amount of days to add, may be negative
1254         * @return the new LocalDate plus the increased days
1255         */
1256        public LocalDate plusDays(int days) {
1257            if (days == 0) {
1258                return this;
1259            }
1260            long instant = getChronology().days().add(getLocalMillis(), days);
1261            return withLocalMillis(instant);
1262        }
1263    
1264        //-----------------------------------------------------------------------
1265        /**
1266         * Returns a copy of this date with the specified period taken away.
1267         * <p>
1268         * If the amount is zero or null, then <code>this</code> is returned.
1269         * <p>
1270         * This method is typically used to subtract complex period instances.
1271         * Subtracting one field is best achieved using methods
1272         * like {@link #minusYears(int)}.
1273         * <p>
1274         * Unsupported time fields are ignored, thus subtracting a period of 24 hours
1275         * will not have any effect.
1276         *
1277         * @param period  the period to reduce this instant by
1278         * @return a copy of this LocalDate with the period taken away
1279         * @throws ArithmeticException if the result exceeds the internal capacity
1280         */
1281        public LocalDate minus(ReadablePeriod period) {
1282            return withPeriodAdded(period, -1);
1283        }
1284    
1285        //-----------------------------------------------------------------------
1286        /**
1287         * Returns a copy of this date minus the specified number of years.
1288         * <p>
1289         * This subtracts the specified number of years from the date.
1290         * If subtracting years makes the day-of-month invalid, it is adjusted to the last valid day in the month.
1291         * This LocalDate instance is immutable and unaffected by this method call.
1292         * <p>
1293         * The following three lines are identical in effect:
1294         * <pre>
1295         * LocalDate subtracted = dt.minusYears(6);
1296         * LocalDate subtracted = dt.minus(Period.years(6));
1297         * LocalDate subtracted = dt.withFieldAdded(DurationFieldType.years(), -6);
1298         * </pre>
1299         *
1300         * @param years  the amount of years to subtract, may be negative
1301         * @return the new LocalDate minus the increased years
1302         */
1303        public LocalDate minusYears(int years) {
1304            if (years == 0) {
1305                return this;
1306            }
1307            long instant = getChronology().years().subtract(getLocalMillis(), years);
1308            return withLocalMillis(instant);
1309        }
1310    
1311        /**
1312         * Returns a copy of this date minus the specified number of months.
1313         * <p>
1314         * This subtracts the specified number of months from the date.
1315         * The subtraction may change the year, but the day-of-month is normally unchanged.
1316         * If subtracting months makes the day-of-month invalid, it is adjusted to the last valid day in the month.
1317         * This LocalDate instance is immutable and unaffected by this method call.
1318         * <p>
1319         * The following three lines are identical in effect:
1320         * <pre>
1321         * LocalDate subtracted = dt.minusMonths(6);
1322         * LocalDate subtracted = dt.minus(Period.months(6));
1323         * LocalDate subtracted = dt.withFieldAdded(DurationFieldType.months(), -6);
1324         * </pre>
1325         *
1326         * @param months  the amount of months to subtract, may be negative
1327         * @return the new LocalDate minus the increased months
1328         */
1329        public LocalDate minusMonths(int months) {
1330            if (months == 0) {
1331                return this;
1332            }
1333            long instant = getChronology().months().subtract(getLocalMillis(), months);
1334            return withLocalMillis(instant);
1335        }
1336    
1337        /**
1338         * Returns a copy of this date minus the specified number of weeks.
1339         * <p>
1340         * This LocalDate instance is immutable and unaffected by this method call.
1341         * <p>
1342         * The following three lines are identical in effect:
1343         * <pre>
1344         * LocalDate subtracted = dt.minusWeeks(6);
1345         * LocalDate subtracted = dt.minus(Period.weeks(6));
1346         * LocalDate subtracted = dt.withFieldAdded(DurationFieldType.weeks(), -6);
1347         * </pre>
1348         *
1349         * @param weeks  the amount of weeks to subtract, may be negative
1350         * @return the new LocalDate minus the increased weeks
1351         */
1352        public LocalDate minusWeeks(int weeks) {
1353            if (weeks == 0) {
1354                return this;
1355            }
1356            long instant = getChronology().weeks().subtract(getLocalMillis(), weeks);
1357            return withLocalMillis(instant);
1358        }
1359    
1360        /**
1361         * Returns a copy of this date minus the specified number of days.
1362         * <p>
1363         * This LocalDate instance is immutable and unaffected by this method call.
1364         * <p>
1365         * The following three lines are identical in effect:
1366         * <pre>
1367         * LocalDate subtracted = dt.minusDays(6);
1368         * LocalDate subtracted = dt.minus(Period.days(6));
1369         * LocalDate subtracted = dt.withFieldAdded(DurationFieldType.days(), -6);
1370         * </pre>
1371         *
1372         * @param days  the amount of days to subtract, may be negative
1373         * @return the new LocalDate minus the increased days
1374         */
1375        public LocalDate minusDays(int days) {
1376            if (days == 0) {
1377                return this;
1378            }
1379            long instant = getChronology().days().subtract(getLocalMillis(), days);
1380            return withLocalMillis(instant);
1381        }
1382    
1383        //-----------------------------------------------------------------------
1384        /**
1385         * Gets the property object for the specified type, which contains many
1386         * useful methods.
1387         *
1388         * @param fieldType  the field type to get the chronology for
1389         * @return the property object
1390         * @throws IllegalArgumentException if the field is null or unsupported
1391         */
1392        public Property property(DateTimeFieldType fieldType) {
1393            if (fieldType == null) {
1394                throw new IllegalArgumentException("The DateTimeFieldType must not be null");
1395            }
1396            if (isSupported(fieldType) == false) {
1397                throw new IllegalArgumentException("Field '" + fieldType + "' is not supported");
1398            }
1399            return new Property(this, fieldType.getField(getChronology()));
1400        }
1401    
1402        //-----------------------------------------------------------------------
1403        /**
1404         * Get the era field value.
1405         *
1406         * @return the era
1407         */
1408        public int getEra() {
1409            return getChronology().era().get(getLocalMillis());
1410        }
1411    
1412        /**
1413         * Get the year of era field value.
1414         *
1415         * @return the year of era
1416         */
1417        public int getCenturyOfEra() {
1418            return getChronology().centuryOfEra().get(getLocalMillis());
1419        }
1420    
1421        /**
1422         * Get the year of era field value.
1423         *
1424         * @return the year of era
1425         */
1426        public int getYearOfEra() {
1427            return getChronology().yearOfEra().get(getLocalMillis());
1428        }
1429    
1430        /**
1431         * Get the year of century field value.
1432         *
1433         * @return the year of century
1434         */
1435        public int getYearOfCentury() {
1436            return getChronology().yearOfCentury().get(getLocalMillis());
1437        }
1438    
1439        /**
1440         * Get the year field value.
1441         *
1442         * @return the year
1443         */
1444        public int getYear() {
1445            return getChronology().year().get(getLocalMillis());
1446        }
1447    
1448        /**
1449         * Get the weekyear field value.
1450         * <p>
1451         * The weekyear is the year that matches with the weekOfWeekyear field.
1452         * In the standard ISO8601 week algorithm, the first week of the year
1453         * is that in which at least 4 days are in the year. As a result of this
1454         * definition, day 1 of the first week may be in the previous year.
1455         * The weekyear allows you to query the effective year for that day.
1456         *
1457         * @return the weekyear
1458         */
1459        public int getWeekyear() {
1460            return getChronology().weekyear().get(getLocalMillis());
1461        }
1462    
1463        /**
1464         * Get the month of year field value.
1465         *
1466         * @return the month of year
1467         */
1468        public int getMonthOfYear() {
1469            return getChronology().monthOfYear().get(getLocalMillis());
1470        }
1471    
1472        /**
1473         * Get the week of weekyear field value.
1474         * <p>
1475         * This field is associated with the "weekyear" via {@link #getWeekyear()}.
1476         * In the standard ISO8601 week algorithm, the first week of the year
1477         * is that in which at least 4 days are in the year. As a result of this
1478         * definition, day 1 of the first week may be in the previous year.
1479         *
1480         * @return the week of a week based year
1481         */
1482        public int getWeekOfWeekyear() {
1483            return getChronology().weekOfWeekyear().get(getLocalMillis());
1484        }
1485    
1486        /**
1487         * Get the day of year field value.
1488         *
1489         * @return the day of year
1490         */
1491        public int getDayOfYear() {
1492            return getChronology().dayOfYear().get(getLocalMillis());
1493        }
1494    
1495        /**
1496         * Get the day of month field value.
1497         * <p>
1498         * The values for the day of month are defined in {@link org.joda.time.DateTimeConstants}.
1499         *
1500         * @return the day of month
1501         */
1502        public int getDayOfMonth() {
1503            return getChronology().dayOfMonth().get(getLocalMillis());
1504        }
1505    
1506        /**
1507         * Get the day of week field value.
1508         * <p>
1509         * The values for the day of week are defined in {@link org.joda.time.DateTimeConstants}.
1510         *
1511         * @return the day of week
1512         */
1513        public int getDayOfWeek() {
1514            return getChronology().dayOfWeek().get(getLocalMillis());
1515        }
1516    
1517        //-----------------------------------------------------------------------
1518        /**
1519         * Returns a copy of this date with the era field updated.
1520         * <p>
1521         * LocalDate is immutable, so there are no set methods.
1522         * Instead, this method returns a new instance with the value of
1523         * era changed.
1524         *
1525         * @param era  the era to set
1526         * @return a copy of this object with the field set
1527         * @throws IllegalArgumentException if the value is invalid
1528         */
1529        public LocalDate withEra(int era) {
1530            return withLocalMillis(getChronology().era().set(getLocalMillis(), era));
1531        }
1532    
1533        /**
1534         * Returns a copy of this date with the century of era field updated.
1535         * <p>
1536         * LocalDate is immutable, so there are no set methods.
1537         * Instead, this method returns a new instance with the value of
1538         * century of era changed.
1539         *
1540         * @param centuryOfEra  the centurey of era to set
1541         * @return a copy of this object with the field set
1542         * @throws IllegalArgumentException if the value is invalid
1543         */
1544        public LocalDate withCenturyOfEra(int centuryOfEra) {
1545            return withLocalMillis(getChronology().centuryOfEra().set(getLocalMillis(), centuryOfEra));
1546        }
1547    
1548        /**
1549         * Returns a copy of this date with the year of era field updated.
1550         * <p>
1551         * LocalDate is immutable, so there are no set methods.
1552         * Instead, this method returns a new instance with the value of
1553         * year of era changed.
1554         *
1555         * @param yearOfEra  the year of era to set
1556         * @return a copy of this object with the field set
1557         * @throws IllegalArgumentException if the value is invalid
1558         */
1559        public LocalDate withYearOfEra(int yearOfEra) {
1560            return withLocalMillis(getChronology().yearOfEra().set(getLocalMillis(), yearOfEra));
1561        }
1562    
1563        /**
1564         * Returns a copy of this date with the year of century field updated.
1565         * <p>
1566         * LocalDate is immutable, so there are no set methods.
1567         * Instead, this method returns a new instance with the value of
1568         * year of century changed.
1569         *
1570         * @param yearOfCentury  the year of century to set
1571         * @return a copy of this object with the field set
1572         * @throws IllegalArgumentException if the value is invalid
1573         */
1574        public LocalDate withYearOfCentury(int yearOfCentury) {
1575            return withLocalMillis(getChronology().yearOfCentury().set(getLocalMillis(), yearOfCentury));
1576        }
1577    
1578        /**
1579         * Returns a copy of this date with the year field updated.
1580         * <p>
1581         * LocalDate is immutable, so there are no set methods.
1582         * Instead, this method returns a new instance with the value of
1583         * year changed.
1584         *
1585         * @param year  the year to set
1586         * @return a copy of this object with the field set
1587         * @throws IllegalArgumentException if the value is invalid
1588         */
1589        public LocalDate withYear(int year) {
1590            return withLocalMillis(getChronology().year().set(getLocalMillis(), year));
1591        }
1592    
1593        /**
1594         * Returns a copy of this date with the weekyear field updated.
1595         * <p>
1596         * The weekyear is the year that matches with the weekOfWeekyear field.
1597         * In the standard ISO8601 week algorithm, the first week of the year
1598         * is that in which at least 4 days are in the year. As a result of this
1599         * definition, day 1 of the first week may be in the previous year.
1600         * The weekyear allows you to query the effective year for that day.
1601         * <p>
1602         * LocalDate is immutable, so there are no set methods.
1603         * Instead, this method returns a new instance with the value of
1604         * weekyear changed.
1605         *
1606         * @param weekyear  the weekyear to set
1607         * @return a copy of this object with the field set
1608         * @throws IllegalArgumentException if the value is invalid
1609         */
1610        public LocalDate withWeekyear(int weekyear) {
1611            return withLocalMillis(getChronology().weekyear().set(getLocalMillis(), weekyear));
1612        }
1613    
1614        /**
1615         * Returns a copy of this date with the month of year field updated.
1616         * <p>
1617         * LocalDate is immutable, so there are no set methods.
1618         * Instead, this method returns a new instance with the value of
1619         * month of year changed.
1620         *
1621         * @param monthOfYear  the month of year to set
1622         * @return a copy of this object with the field set
1623         * @throws IllegalArgumentException if the value is invalid
1624         */
1625        public LocalDate withMonthOfYear(int monthOfYear) {
1626            return withLocalMillis(getChronology().monthOfYear().set(getLocalMillis(), monthOfYear));
1627        }
1628    
1629        /**
1630         * Returns a copy of this date with the week of weekyear field updated.
1631         * <p>
1632         * This field is associated with the "weekyear" via {@link #withWeekyear(int)}.
1633         * In the standard ISO8601 week algorithm, the first week of the year
1634         * is that in which at least 4 days are in the year. As a result of this
1635         * definition, day 1 of the first week may be in the previous year.
1636         * <p>
1637         * LocalDate is immutable, so there are no set methods.
1638         * Instead, this method returns a new instance with the value of
1639         * week of weekyear changed.
1640         *
1641         * @param weekOfWeekyear  the week of weekyear to set
1642         * @return a copy of this object with the field set
1643         * @throws IllegalArgumentException if the value is invalid
1644         */
1645        public LocalDate withWeekOfWeekyear(int weekOfWeekyear) {
1646            return withLocalMillis(getChronology().weekOfWeekyear().set(getLocalMillis(), weekOfWeekyear));
1647        }
1648    
1649        /**
1650         * Returns a copy of this date with the day of year field updated.
1651         * <p>
1652         * LocalDate is immutable, so there are no set methods.
1653         * Instead, this method returns a new instance with the value of
1654         * day of year changed.
1655         *
1656         * @param dayOfYear  the day of year to set
1657         * @return a copy of this object with the field set
1658         * @throws IllegalArgumentException if the value is invalid
1659         */
1660        public LocalDate withDayOfYear(int dayOfYear) {
1661            return withLocalMillis(getChronology().dayOfYear().set(getLocalMillis(), dayOfYear));
1662        }
1663    
1664        /**
1665         * Returns a copy of this date with the day of month field updated.
1666         * <p>
1667         * LocalDate is immutable, so there are no set methods.
1668         * Instead, this method returns a new instance with the value of
1669         * day of month changed.
1670         *
1671         * @param dayOfMonth  the day of month to set
1672         * @return a copy of this object with the field set
1673         * @throws IllegalArgumentException if the value is invalid
1674         */
1675        public LocalDate withDayOfMonth(int dayOfMonth) {
1676            return withLocalMillis(getChronology().dayOfMonth().set(getLocalMillis(), dayOfMonth));
1677        }
1678    
1679        /**
1680         * Returns a copy of this date with the day of week field updated.
1681         * <p>
1682         * LocalDate is immutable, so there are no set methods.
1683         * Instead, this method returns a new instance with the value of
1684         * day of week changed.
1685         *
1686         * @param dayOfWeek  the day of week to set
1687         * @return a copy of this object with the field set
1688         * @throws IllegalArgumentException if the value is invalid
1689         */
1690        public LocalDate withDayOfWeek(int dayOfWeek) {
1691            return withLocalMillis(getChronology().dayOfWeek().set(getLocalMillis(), dayOfWeek));
1692        }
1693    
1694        //-----------------------------------------------------------------------
1695        /**
1696         * Get the era property which provides access to advanced functionality.
1697         *
1698         * @return the era property
1699         */
1700        public Property era() {
1701            return new Property(this, getChronology().era());
1702        }
1703    
1704        /**
1705         * Get the century of era property which provides access to advanced functionality.
1706         *
1707         * @return the year of era property
1708         */
1709        public Property centuryOfEra() {
1710            return new Property(this, getChronology().centuryOfEra());
1711        }
1712    
1713        /**
1714         * Get the year of century property which provides access to advanced functionality.
1715         *
1716         * @return the year of era property
1717         */
1718        public Property yearOfCentury() {
1719            return new Property(this, getChronology().yearOfCentury());
1720        }
1721    
1722        /**
1723         * Get the year of era property which provides access to advanced functionality.
1724         *
1725         * @return the year of era property
1726         */
1727        public Property yearOfEra() {
1728            return new Property(this, getChronology().yearOfEra());
1729        }
1730    
1731        /**
1732         * Get the year property which provides access to advanced functionality.
1733         *
1734         * @return the year property
1735         */
1736        public Property year() {
1737            return new Property(this, getChronology().year());
1738        }
1739    
1740        /**
1741         * Get the weekyear property which provides access to advanced functionality.
1742         *
1743         * @return the weekyear property
1744         */
1745        public Property weekyear() {
1746            return new Property(this, getChronology().weekyear());
1747        }
1748    
1749        /**
1750         * Get the month of year property which provides access to advanced functionality.
1751         *
1752         * @return the month of year property
1753         */
1754        public Property monthOfYear() {
1755            return new Property(this, getChronology().monthOfYear());
1756        }
1757    
1758        /**
1759         * Get the week of a week based year property which provides access to advanced functionality.
1760         *
1761         * @return the week of a week based year property
1762         */
1763        public Property weekOfWeekyear() {
1764            return new Property(this, getChronology().weekOfWeekyear());
1765        }
1766    
1767        /**
1768         * Get the day of year property which provides access to advanced functionality.
1769         *
1770         * @return the day of year property
1771         */
1772        public Property dayOfYear() {
1773            return new Property(this, getChronology().dayOfYear());
1774        }
1775    
1776        /**
1777         * Get the day of month property which provides access to advanced functionality.
1778         *
1779         * @return the day of month property
1780         */
1781        public Property dayOfMonth() {
1782            return new Property(this, getChronology().dayOfMonth());
1783        }
1784    
1785        /**
1786         * Get the day of week property which provides access to advanced functionality.
1787         *
1788         * @return the day of week property
1789         */
1790        public Property dayOfWeek() {
1791            return new Property(this, getChronology().dayOfWeek());
1792        }
1793    
1794        //-----------------------------------------------------------------------
1795        /**
1796         * Output the date time in ISO8601 format (yyyy-MM-dd).
1797         *
1798         * @return ISO8601 time formatted string.
1799         */
1800        @ToString
1801        public String toString() {
1802            return ISODateTimeFormat.date().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         * @see org.joda.time.format.DateTimeFormat
1810         */
1811        public String toString(String pattern) {
1812            if (pattern == null) {
1813                return toString();
1814            }
1815            return DateTimeFormat.forPattern(pattern).print(this);
1816        }
1817    
1818        /**
1819         * Output the date using the specified format pattern.
1820         *
1821         * @param pattern  the pattern specification, null means use <code>toString</code>
1822         * @param locale  Locale to use, null means default
1823         * @see org.joda.time.format.DateTimeFormat
1824         */
1825        public String toString(String pattern, Locale locale) throws IllegalArgumentException {
1826            if (pattern == null) {
1827                return toString();
1828            }
1829            return DateTimeFormat.forPattern(pattern).withLocale(locale).print(this);
1830        }
1831    
1832        //-----------------------------------------------------------------------
1833        /**
1834         * LocalDate.Property binds a LocalDate to a DateTimeField allowing
1835         * powerful datetime functionality to be easily accessed.
1836         * <p>
1837         * The simplest use of this class is as an alternative get method, here used to
1838         * get the year '1972' (as an int) and the month 'December' (as a String).
1839         * <pre>
1840         * LocalDate dt = new LocalDate(1972, 12, 3, 0, 0);
1841         * int year = dt.year().get();
1842         * String monthStr = dt.month().getAsText();
1843         * </pre>
1844         * <p>
1845         * Methods are also provided that allow date modification. These return
1846         * new instances of LocalDate - they do not modify the original. The example
1847         * below yields two independent immutable date objects 20 years apart.
1848         * <pre>
1849         * LocalDate dt = new LocalDate(1972, 12, 3);
1850         * LocalDate dt1920 = dt.year().setCopy(1920);
1851         * </pre>
1852         * <p>
1853         * LocalDate.Property itself is thread-safe and immutable, as well as the
1854         * LocalDate being operated on.
1855         *
1856         * @author Stephen Colebourne
1857         * @author Brian S O'Neill
1858         * @since 1.3
1859         */
1860        public static final class Property extends AbstractReadableInstantFieldProperty {
1861            
1862            /** Serialization version */
1863            private static final long serialVersionUID = -3193829732634L;
1864            
1865            /** The instant this property is working against */
1866            private transient LocalDate iInstant;
1867            /** The field this property is working against */
1868            private transient DateTimeField iField;
1869            
1870            /**
1871             * Constructor.
1872             * 
1873             * @param instant  the instant to set
1874             * @param field  the field to use
1875             */
1876            Property(LocalDate instant, DateTimeField field) {
1877                super();
1878                iInstant = instant;
1879                iField = field;
1880            }
1881            
1882            /**
1883             * Writes the property in a safe serialization format.
1884             */
1885            private void writeObject(ObjectOutputStream oos) throws IOException {
1886                oos.writeObject(iInstant);
1887                oos.writeObject(iField.getType());
1888            }
1889    
1890            /**
1891             * Reads the property from a safe serialization format.
1892             */
1893            private void readObject(ObjectInputStream oos) throws IOException, ClassNotFoundException {
1894                iInstant = (LocalDate) oos.readObject();
1895                DateTimeFieldType type = (DateTimeFieldType) oos.readObject();
1896                iField = type.getField(iInstant.getChronology());
1897            }
1898    
1899            //-----------------------------------------------------------------------
1900            /**
1901             * Gets the field being used.
1902             * 
1903             * @return the field
1904             */
1905            public DateTimeField getField() {
1906                return iField;
1907            }
1908            
1909            /**
1910             * Gets the milliseconds of the date that this property is linked to.
1911             * 
1912             * @return the milliseconds
1913             */
1914            protected long getMillis() {
1915                return iInstant.getLocalMillis();
1916            }
1917            
1918            /**
1919             * Gets the chronology of the datetime that this property is linked to.
1920             * 
1921             * @return the chronology
1922             * @since 1.4
1923             */
1924            protected Chronology getChronology() {
1925                return iInstant.getChronology();
1926            }
1927            
1928            /**
1929             * Gets the LocalDate object linked to this property.
1930             * 
1931             * @return the linked LocalDate
1932             */
1933            public LocalDate getLocalDate() {
1934                return iInstant;
1935            }
1936            
1937            //-----------------------------------------------------------------------
1938            /**
1939             * Adds to this field in a copy of this LocalDate.
1940             * <p>
1941             * The LocalDate attached to this property is unchanged by this call.
1942             *
1943             * @param value  the value to add to the field in the copy
1944             * @return a copy of the LocalDate with the field value changed
1945             * @throws IllegalArgumentException if the value isn't valid
1946             */
1947            public LocalDate addToCopy(int value) {
1948                return iInstant.withLocalMillis(iField.add(iInstant.getLocalMillis(), value));
1949            }
1950            
1951            /**
1952             * Adds to this field, possibly wrapped, in a copy of this LocalDate.
1953             * A field wrapped operation only changes this field.
1954             * Thus 31st January addWrapField one day goes to the 1st January.
1955             * <p>
1956             * The LocalDate attached to this property is unchanged by this call.
1957             *
1958             * @param value  the value to add to the field in the copy
1959             * @return a copy of the LocalDate with the field value changed
1960             * @throws IllegalArgumentException if the value isn't valid
1961             */
1962            public LocalDate addWrapFieldToCopy(int value) {
1963                return iInstant.withLocalMillis(iField.addWrapField(iInstant.getLocalMillis(), value));
1964            }
1965            
1966            //-----------------------------------------------------------------------
1967            /**
1968             * Sets this field in a copy of the LocalDate.
1969             * <p>
1970             * The LocalDate attached to this property is unchanged by this call.
1971             *
1972             * @param value  the value to set the field in the copy to
1973             * @return a copy of the LocalDate with the field value changed
1974             * @throws IllegalArgumentException if the value isn't valid
1975             */
1976            public LocalDate setCopy(int value) {
1977                return iInstant.withLocalMillis(iField.set(iInstant.getLocalMillis(), value));
1978            }
1979            
1980            /**
1981             * Sets this field in a copy of the LocalDate to a parsed text value.
1982             * <p>
1983             * The LocalDate attached to this property is unchanged by this call.
1984             *
1985             * @param text  the text value to set
1986             * @param locale  optional locale to use for selecting a text symbol
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, Locale locale) {
1991                return iInstant.withLocalMillis(iField.set(iInstant.getLocalMillis(), text, locale));
1992            }
1993            
1994            /**
1995             * Sets this field in a copy of the LocalDate to a parsed text value.
1996             * <p>
1997             * The LocalDate attached to this property is unchanged by this call.
1998             *
1999             * @param text  the text value to set
2000             * @return a copy of the LocalDate with the field value changed
2001             * @throws IllegalArgumentException if the text value isn't valid
2002             */
2003            public LocalDate setCopy(String text) {
2004                return setCopy(text, null);
2005            }
2006            
2007            //-----------------------------------------------------------------------
2008            /**
2009             * Returns a new LocalDate with this field set to the maximum value
2010             * for this field.
2011             * <p>
2012             * This operation is useful for obtaining a LocalDate on the last day
2013             * of the month, as month lengths vary.
2014             * <pre>
2015             * LocalDate lastDayOfMonth = dt.dayOfMonth().withMaximumValue();
2016             * </pre>
2017             * <p>
2018             * The LocalDate attached to this property is unchanged by this call.
2019             *
2020             * @return a copy of the LocalDate with this field set to its maximum
2021             */
2022            public LocalDate withMaximumValue() {
2023                return setCopy(getMaximumValue());
2024            }
2025            
2026            /**
2027             * Returns a new LocalDate with this field set to the minimum value
2028             * for this field.
2029             * <p>
2030             * The LocalDate attached to this property is unchanged by this call.
2031             *
2032             * @return a copy of the LocalDate with this field set to its minimum
2033             */
2034            public LocalDate withMinimumValue() {
2035                return setCopy(getMinimumValue());
2036            }
2037            
2038            //-----------------------------------------------------------------------
2039            /**
2040             * Rounds to the lowest whole unit of this field on a copy of this
2041             * LocalDate.
2042             * <p>
2043             * For example, rounding floor on the hourOfDay field of a LocalDate
2044             * where the time is 10:30 would result in new LocalDate with the
2045             * time of 10:00.
2046             *
2047             * @return a copy of the LocalDate with the field value changed
2048             */
2049            public LocalDate roundFloorCopy() {
2050                return iInstant.withLocalMillis(iField.roundFloor(iInstant.getLocalMillis()));
2051            }
2052            
2053            /**
2054             * Rounds to the highest whole unit of this field on a copy of this
2055             * LocalDate.
2056             * <p>
2057             * For example, rounding floor on the hourOfDay field of a LocalDate
2058             * where the time is 10:30 would result in new LocalDate with the
2059             * time of 11:00.
2060             *
2061             * @return a copy of the LocalDate with the field value changed
2062             */
2063            public LocalDate roundCeilingCopy() {
2064                return iInstant.withLocalMillis(iField.roundCeiling(iInstant.getLocalMillis()));
2065            }
2066            
2067            /**
2068             * Rounds to the nearest whole unit of this field on a copy of this
2069             * LocalDate, favoring the floor if halfway.
2070             *
2071             * @return a copy of the LocalDate with the field value changed
2072             */
2073            public LocalDate roundHalfFloorCopy() {
2074                return iInstant.withLocalMillis(iField.roundHalfFloor(iInstant.getLocalMillis()));
2075            }
2076            
2077            /**
2078             * Rounds to the nearest whole unit of this field on a copy of this
2079             * LocalDate, favoring the ceiling if halfway.
2080             *
2081             * @return a copy of the LocalDate with the field value changed
2082             */
2083            public LocalDate roundHalfCeilingCopy() {
2084                return iInstant.withLocalMillis(iField.roundHalfCeiling(iInstant.getLocalMillis()));
2085            }
2086            
2087            /**
2088             * Rounds to the nearest whole unit of this field on a copy of this
2089             * LocalDate.  If halfway, the ceiling is favored over the floor
2090             * only if it makes this field's value even.
2091             *
2092             * @return a copy of the LocalDate with the field value changed
2093             */
2094            public LocalDate roundHalfEvenCopy() {
2095                return iInstant.withLocalMillis(iField.roundHalfEven(iInstant.getLocalMillis()));
2096            }
2097        }
2098    
2099    }