View Javadoc

1   /*
2    *  Copyright 2001-2013 Stephen Colebourne
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  package org.joda.time;
17  
18  import java.io.IOException;
19  import java.io.ObjectInputStream;
20  import java.io.ObjectOutputStream;
21  import java.io.Serializable;
22  import java.util.Calendar;
23  import java.util.Date;
24  import java.util.GregorianCalendar;
25  import java.util.HashSet;
26  import java.util.Locale;
27  import java.util.Set;
28  import java.util.TimeZone;
29  
30  import org.joda.convert.FromString;
31  import org.joda.convert.ToString;
32  import org.joda.time.base.BaseLocal;
33  import org.joda.time.chrono.ISOChronology;
34  import org.joda.time.convert.ConverterManager;
35  import org.joda.time.convert.PartialConverter;
36  import org.joda.time.field.AbstractReadableInstantFieldProperty;
37  import org.joda.time.field.FieldUtils;
38  import org.joda.time.format.DateTimeFormat;
39  import org.joda.time.format.DateTimeFormatter;
40  import org.joda.time.format.ISODateTimeFormat;
41  
42  /**
43   * LocalDate is an immutable datetime class representing a date
44   * without a time zone.
45   * <p>
46   * LocalDate implements the {@link ReadablePartial} interface.
47   * To do this, the interface methods focus on the key fields -
48   * Year, MonthOfYear and DayOfMonth.
49   * However, <b>all</b> date fields may in fact be queried.
50   * <p>
51   * LocalDate differs from DateMidnight in that this class does not
52   * have a time zone and does not represent a single instant in time.
53   * <p>
54   * Calculations on LocalDate are performed using a {@link Chronology}.
55   * This chronology will be set internally to be in the UTC time zone
56   * for all calculations.
57   *
58   * <p>Each individual field can be queried in two ways:
59   * <ul>
60   * <li><code>getMonthOfYear()</code>
61   * <li><code>monthOfYear().get()</code>
62   * </ul>
63   * The second technique also provides access to other useful methods on the
64   * field:
65   * <ul>
66   * <li>numeric value
67   * <li>text value
68   * <li>short text value
69   * <li>maximum/minimum values
70   * <li>add/subtract
71   * <li>set
72   * <li>rounding
73   * </ul>
74   *
75   * <p>
76   * LocalDate is thread-safe and immutable, provided that the Chronology is as well.
77   * All standard Chronology classes supplied are thread-safe and immutable.
78   *
79   * @author Stephen Colebourne
80   * @since 1.3
81   */
82  public final class LocalDate
83          extends BaseLocal
84          implements ReadablePartial, Serializable {
85  
86      /** Serialization lock */
87      private static final long serialVersionUID = -8775358157899L;
88  
89      /** The index of the year field in the field array */
90      private static final int YEAR = 0;
91      /** The index of the monthOfYear field in the field array */
92      private static final int MONTH_OF_YEAR = 1;
93      /** The index of the dayOfMonth field in the field array */
94      private static final int DAY_OF_MONTH = 2;
95      /** Set of known duration types. */
96      private static final Set<DurationFieldType> DATE_DURATION_TYPES = new HashSet<DurationFieldType>();
97      static {
98          DATE_DURATION_TYPES.add(DurationFieldType.days());
99          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 }