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