KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > joda > time > LocalDate


1 /*
2  * Copyright 2001-2006 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 JavaDoc;
19 import java.io.ObjectInputStream JavaDoc;
20 import java.io.ObjectOutputStream JavaDoc;
21 import java.io.Serializable JavaDoc;
22 import java.util.Calendar JavaDoc;
23 import java.util.Date JavaDoc;
24 import java.util.HashSet JavaDoc;
25 import java.util.Locale JavaDoc;
26 import java.util.Set JavaDoc;
27
28 import org.joda.time.base.AbstractPartial;
29 import org.joda.time.chrono.ISOChronology;
30 import org.joda.time.convert.ConverterManager;
31 import org.joda.time.convert.PartialConverter;
32 import org.joda.time.field.AbstractReadableInstantFieldProperty;
33 import org.joda.time.field.FieldUtils;
34 import org.joda.time.format.DateTimeFormat;
35 import org.joda.time.format.ISODateTimeFormat;
36
37 /**
38  * LocalDate is an immutable datetime class representing a date
39  * without a time zone.
40  * <p>
41  * LocalDate implements the {@link ReadablePartial} interface.
42  * To do this, the interface methods focus on the key fields -
43  * Year, MonthOfYear and DayOfMonth.
44  * However, <b>all</b> date fields may in fact be queried.
45  * <p>
46  * LocalDate differs from DateMidnight in that this class does not
47  * have a time zone and does not represent a single instant in time.
48  * <p>
49  * Calculations on LocalDate are performed using a {@link Chronology}.
50  * This chronology will be set internally to be in the UTC time zone
51  * for all calculations.
52  *
53  * <p>Each individual field can be queried in two ways:
54  * <ul>
55  * <li><code>getMonthOfYear()</code>
56  * <li><code>monthOfYear().get()</code>
57  * </ul>
58  * The second technique also provides access to other useful methods on the
59  * field:
60  * <ul>
61  * <li>numeric value
62  * <li>text value
63  * <li>short text value
64  * <li>maximum/minimum values
65  * <li>add/subtract
66  * <li>set
67  * <li>rounding
68  * </ul>
69  *
70  * <p>
71  * LocalDate is thread-safe and immutable, provided that the Chronology is as well.
72  * All standard Chronology classes supplied are thread-safe and immutable.
73  *
74  * @author Stephen Colebourne
75  * @since 1.3
76  */

77 public final class LocalDate
78         extends AbstractPartial
79         implements ReadablePartial, Serializable JavaDoc {
80
81     /** Serialization lock */
82     private static final long serialVersionUID = -8775358157899L;
83
84     /** The index of the year field in the field array */
85     private static final int YEAR = 0;
86     /** The index of the monthOfYear field in the field array */
87     private static final int MONTH_OF_YEAR = 1;
88     /** The index of the dayOfMonth field in the field array */
89     private static final int DAY_OF_MONTH = 2;
90     /** Set of known duration types. */
91     private static final Set JavaDoc DATE_DURATION_TYPES = new HashSet JavaDoc();
92     static {
93         DATE_DURATION_TYPES.add(DurationFieldType.days());
94         DATE_DURATION_TYPES.add(DurationFieldType.weeks());
95         DATE_DURATION_TYPES.add(DurationFieldType.months());
96         DATE_DURATION_TYPES.add(DurationFieldType.weekyears());
97         DATE_DURATION_TYPES.add(DurationFieldType.years());
98         DATE_DURATION_TYPES.add(DurationFieldType.centuries());
99         // eras are supported, although the DurationField generally isn't
100
DATE_DURATION_TYPES.add(DurationFieldType.eras());
101     }
102
103     /** The local millis from 1970-01-01T00:00:00 */
104     private long iLocalMillis;
105     /** The chronology to use in UTC */
106     private Chronology iChronology;
107
108     //-----------------------------------------------------------------------
109
/**
110      * Constructs a LocalDate from a <code>java.util.Calendar</code>
111      * using exactly the same field values avoiding any time zone effects.
112      * <p>
113      * Each field is queried from the Calendar and assigned to the LocalDate.
114      * This is useful if you have been using the Calendar as a local date,
115      * ignoing the zone.
116      * <p>
117      * This factory method ignores the type of the calendar and always
118      * creates a LocalDate with ISO chronology. It is expected that you
119      * will only pass in instances of <code>GregorianCalendar</code> however
120      * this is not validated.
121      *
122      * @param calendar the Calendar to extract fields from
123      * @return the created LocalDate
124      * @throws IllegalArgumentException if the calendar is null
125      * @throws IllegalArgumentException if the date is invalid for the ISO chronology
126      */

127     public static LocalDate fromCalendarFields(Calendar JavaDoc calendar) {
128         if (calendar == null) {
129             throw new IllegalArgumentException JavaDoc("The calendar must not be null");
130         }
131         return new LocalDate(
132             calendar.get(Calendar.YEAR),
133             calendar.get(Calendar.MONTH) + 1,
134             calendar.get(Calendar.DAY_OF_MONTH)
135         );
136     }
137
138     /**
139      * Constructs a LocalDate from a <code>java.util.Date</code>
140      * using exactly the same field values avoiding any time zone effects.
141      * <p>
142      * Each field is queried from the Date and assigned to the LocalDate.
143      * This is useful if you have been using the Date as a local date,
144      * ignoing the zone.
145      * <p>
146      * This factory method always creates a LocalDate with ISO chronology.
147      *
148      * @param date the Date to extract fields from
149      * @return the created LocalDate
150      * @throws IllegalArgumentException if the calendar is null
151      * @throws IllegalArgumentException if the date is invalid for the ISO chronology
152      */

153     public static LocalDate fromDateFields(Date JavaDoc date) {
154         if (date == null) {
155             throw new IllegalArgumentException JavaDoc("The date must not be null");
156         }
157         return new LocalDate(
158             date.getYear() + 1900,
159             date.getMonth() + 1,
160             date.getDate()
161         );
162     }
163
164     //-----------------------------------------------------------------------
165
/**
166      * Constructs an instance set to the current local time evaluated using
167      * ISO chronology in the default zone.
168      * <p>
169      * Once the constructor is completed, the zone is no longer used.
170      */

171     public LocalDate() {
172         this(DateTimeUtils.currentTimeMillis(), ISOChronology.getInstance());
173     }
174
175     /**
176      * Constructs an instance set to the current local time evaluated using
177      * ISO chronology in the specified zone.
178      * <p>
179      * If the specified time zone is null, the default zone is used.
180      * Once the constructor is completed, the zone is no longer used.
181      *
182      * @param zone the time zone, null means default zone
183      */

184     public LocalDate(DateTimeZone zone) {
185         this(DateTimeUtils.currentTimeMillis(), ISOChronology.getInstance(zone));
186     }
187
188     /**
189      * Constructs an instance set to the current local time evaluated using
190      * specified chronology.
191      * <p>
192      * If the chronology is null, ISO chronology in the default time zone is used.
193      * Once the constructor is completed, the zone is no longer used.
194      *
195      * @param chronology the chronology, null means ISOChronology in default zone
196      */

197     public LocalDate(Chronology chronology) {
198         this(DateTimeUtils.currentTimeMillis(), chronology);
199     }
200
201     //-----------------------------------------------------------------------
202
/**
203      * Constructs an instance set to the local time defined by the specified
204      * instant evaluated using ISO chronology in the default zone.
205      * <p>
206      * Once the constructor is completed, the zone is no longer used.
207      *
208      * @param instant the milliseconds from 1970-01-01T00:00:00Z
209      */

210     public LocalDate(long instant) {
211         this(instant, ISOChronology.getInstance());
212     }
213
214     /**
215      * Constructs an instance set to the local time defined by the specified
216      * instant evaluated using ISO chronology in the specified zone.
217      * <p>
218      * If the specified time zone is null, the default zone is used.
219      * Once the constructor is completed, the zone is no longer used.
220      *
221      * @param instant the milliseconds from 1970-01-01T00:00:00Z
222      * @param zone the time zone, null means default zone
223      */

224     public LocalDate(long instant, DateTimeZone zone) {
225         this(instant, ISOChronology.getInstance(zone));
226     }
227
228     /**
229      * Constructs an instance set to the local time defined by the specified
230      * instant evaluated using the specified chronology.
231      * <p>
232      * If the chronology is null, ISO chronology in the default zone is used.
233      * Once the constructor is completed, the zone is no longer used.
234      *
235      * @param instant the milliseconds from 1970-01-01T00:00:00Z
236      * @param chronology the chronology, null means ISOChronology in default zone
237      */

238     public LocalDate(long instant, Chronology chronology) {
239         chronology = DateTimeUtils.getChronology(chronology);
240         
241         long localMillis = chronology.getZone().getMillisKeepLocal(DateTimeZone.UTC, instant);
242         chronology = chronology.withUTC();
243         chronology.dayOfMonth().roundFloor(localMillis);
244         iLocalMillis = localMillis;
245         iChronology = chronology;
246     }
247
248     //-----------------------------------------------------------------------
249
/**
250      * Constructs an instance from an Object that represents a datetime.
251      * The time zone will be retrieved from the object if possible,
252      * otherwise the default time zone will be used.
253      * <p>
254      * If the object contains no chronology, <code>ISOChronology</code> is used.
255      * Once the constructor is completed, the zone is no longer used.
256      * <p>
257      * The recognised object types are defined in
258      * {@link org.joda.time.convert.ConverterManager ConverterManager} and
259      * include ReadablePartial, ReadableInstant, String, Calendar and Date.
260      * The String formats are described by {@link ISODateTimeFormat#localDateParser()}.
261      * The default String converter ignores the zone and only parses the field values.
262      *
263      * @param instant the datetime object
264      * @throws IllegalArgumentException if the instant is invalid
265      */

266     public LocalDate(Object JavaDoc instant) {
267         this(instant, (Chronology) null);
268     }
269
270     /**
271      * Constructs an instance from an Object that represents a datetime,
272      * forcing the time zone to that specified.
273      * <p>
274      * If the object contains no chronology, <code>ISOChronology</code> is used.
275      * If the specified time zone is null, the default zone is used.
276      * Once the constructor is completed, the zone is no longer used.
277      * <p>
278      * The recognised object types are defined in
279      * {@link org.joda.time.convert.ConverterManager ConverterManager} and
280      * include ReadablePartial, ReadableInstant, String, Calendar and Date.
281      * The String formats are described by {@link ISODateTimeFormat#localDateParser()}.
282      * The default String converter ignores the zone and only parses the field values.
283      *
284      * @param instant the datetime object
285      * @param zone the time zone
286      * @throws IllegalArgumentException if the instant is invalid
287      */

288     public LocalDate(Object JavaDoc instant, DateTimeZone zone) {
289         PartialConverter converter = ConverterManager.getInstance().getPartialConverter(instant);
290         Chronology chronology = converter.getChronology(instant, zone);
291         chronology = DateTimeUtils.getChronology(chronology);
292         iChronology = chronology.withUTC();
293         int[] values = converter.getPartialValues(this, instant, chronology, ISODateTimeFormat.localDateParser());
294         iLocalMillis = iChronology.getDateTimeMillis(values[0], values[1], values[2], 0);
295     }
296
297     /**
298      * Constructs an instance from an Object that represents a datetime,
299      * using the specified chronology.
300      * <p>
301      * If the chronology is null, ISO in the default time zone is used.
302      * Once the constructor is completed, the zone is no longer used.
303      * <p>
304      * The recognised object types are defined in
305      * {@link org.joda.time.convert.ConverterManager ConverterManager} and
306      * include ReadablePartial, ReadableInstant, String, Calendar and Date.
307      * The String formats are described by {@link ISODateTimeFormat#localDateParser()}.
308      * The default String converter ignores the zone and only parses the field values.
309      *
310      * @param instant the datetime object
311      * @param chronology the chronology
312      * @throws IllegalArgumentException if the instant is invalid
313      */

314     public LocalDate(Object JavaDoc instant, Chronology chronology) {
315         PartialConverter converter = ConverterManager.getInstance().getPartialConverter(instant);
316         chronology = converter.getChronology(instant, chronology);
317         chronology = DateTimeUtils.getChronology(chronology);
318         iChronology = chronology.withUTC();
319         int[] values = converter.getPartialValues(this, instant, chronology, ISODateTimeFormat.localDateParser());
320         iLocalMillis = iChronology.getDateTimeMillis(values[0], values[1], values[2], 0);
321     }
322
323     //-----------------------------------------------------------------------
324
/**
325      * Constructs an instance set to the specified date and time
326      * using <code>ISOChronology</code>.
327      *
328      * @param year the year
329      * @param monthOfYear the month of the year
330      * @param dayOfMonth the day of the month
331      */

332     public LocalDate(
333             int year,
334             int monthOfYear,
335             int dayOfMonth) {
336         this(year, monthOfYear, dayOfMonth, ISOChronology.getInstanceUTC());
337     }
338
339     /**
340      * Constructs an instance set to the specified date and time
341      * using the specified chronology, whose zone is ignored.
342      * <p>
343      * If the chronology is null, <code>ISOChronology</code> is used.
344      *
345      * @param year the year
346      * @param monthOfYear the month of the year
347      * @param dayOfMonth the day of the month
348      * @param chronology the chronology, null means ISOChronology in default zone
349      */

350     public LocalDate(
351             int year,
352             int monthOfYear,
353             int dayOfMonth,
354             Chronology chronology) {
355         super();
356         chronology = DateTimeUtils.getChronology(chronology).withUTC();
357         long instant = chronology.getDateTimeMillis(year, monthOfYear, dayOfMonth, 0);
358         iChronology = chronology;
359         iLocalMillis = instant;
360     }
361
362     //-----------------------------------------------------------------------
363
/**
364      * Gets the number of fields in this partial, which is three.
365      * The supported fields are Year, MonthOfYear and DayOfMonth.
366      * Note that all fields from day and above may in fact be queried via
367      * other methods.
368      *
369      * @return the field count, three
370      */

371     public int size() {
372         return 3;
373     }
374
375     /**
376      * Gets the field for a specific index in the chronology specified.
377      * <p>
378      * This method must not use any instance variables.
379      *
380      * @param index the index to retrieve
381      * @param chrono the chronology to use
382      * @return the field
383      */

384     protected DateTimeField getField(int index, Chronology chrono) {
385         switch (index) {
386             case YEAR:
387                 return chrono.year();
388             case MONTH_OF_YEAR:
389                 return chrono.monthOfYear();
390             case DAY_OF_MONTH:
391                 return chrono.dayOfMonth();
392             default:
393                 throw new IndexOutOfBoundsException JavaDoc("Invalid index: " + index);
394         }
395     }
396
397     /**
398      * Gets the value of the field at the specifed index.
399      * <p>
400      * This method is required to support the <code>ReadablePartial</code>
401      * interface. The supported fields are Year, MonthOfYear and DayOfMonth.
402      * Note that all fields from day and above may in fact be queried via
403      * other methods.
404      *
405      * @param index the index, zero to two
406      * @return the value
407      * @throws IndexOutOfBoundsException if the index is invalid
408      */

409     public int getValue(int index) {
410         switch (index) {
411             case YEAR:
412                 return getChronology().year().get(getLocalMillis());
413             case MONTH_OF_YEAR:
414                 return getChronology().monthOfYear().get(getLocalMillis());
415             case DAY_OF_MONTH:
416                 return getChronology().dayOfMonth().get(getLocalMillis());
417             default:
418                 throw new IndexOutOfBoundsException JavaDoc("Invalid index: " + index);
419         }
420     }
421
422     //-----------------------------------------------------------------------
423
/**
424      * Get the value of one of the fields of a datetime.
425      * <p>
426      * This method gets the value of the specified field.
427      * For example:
428      * <pre>
429      * LocalDate dt = LocalDate.nowDefaultZone();
430      * int year = dt.get(DateTimeFieldType.year());
431      * </pre>
432      *
433      * @param fieldType a field type, usually obtained from DateTimeFieldType, not null
434      * @return the value of that field
435      * @throws IllegalArgumentException if the field type is null or unsupported
436      */

437     public int get(DateTimeFieldType fieldType) {
438         if (fieldType == null) {
439             throw new IllegalArgumentException JavaDoc("The DateTimeFieldType must not be null");
440         }
441         if (isSupported(fieldType) == false) {
442             throw new IllegalArgumentException JavaDoc("Field '" + fieldType + "' is not supported");
443         }
444         return fieldType.getField(getChronology()).get(getLocalMillis());
445     }
446
447     /**
448      * Checks if the field type specified is supported by this
449      * local date and chronology.
450      * This can be used to avoid exceptions in {@link #get(DateTimeFieldType)}.
451      *
452      * @param type a field type, usually obtained from DateTimeFieldType
453      * @return true if the field type is supported
454      */

455     public boolean isSupported(DateTimeFieldType type) {
456         if (type == null) {
457             return false;
458         }
459         DurationFieldType durType = type.getDurationType();
460         if (DATE_DURATION_TYPES.contains(durType) ||
461                 durType.getField(getChronology()).getUnitMillis() >=
462                     getChronology().days().getUnitMillis()) {
463             return type.getField(getChronology()).isSupported();
464         }
465         return false;
466     }
467
468     /**
469      * Checks if the duration type specified is supported by this
470      * local date and chronology.
471      *
472      * @param type a duration type, usually obtained from DurationFieldType
473      * @return true if the field type is supported
474      */

475     public boolean isSupported(DurationFieldType type) {
476         if (type == null) {
477             return false;
478         }
479         DurationField field = type.getField(getChronology());
480         if (DATE_DURATION_TYPES.contains(type) ||
481             field.getUnitMillis() >= getChronology().days().getUnitMillis()) {
482             return field.isSupported();
483         }
484         return false;
485     }
486
487     //-----------------------------------------------------------------------
488
/**
489      * Gets the local milliseconds from the Java epoch
490      * of 1970-01-01T00:00:00 (not fixed to any specific time zone).
491      *
492      * @return the number of milliseconds since 1970-01-01T00:00:00
493      */

494     long getLocalMillis() {
495         return iLocalMillis;
496     }
497
498     /**
499      * Gets the chronology of the date.
500      *
501      * @return the Chronology that the date is using
502      */

503     public Chronology getChronology() {
504         return iChronology;
505     }
506
507     //-----------------------------------------------------------------------
508
/**
509      * Converts this LocalDate to a full datetime at midnight using the
510      * default time zone.
511      * <p>
512      * This instance is immutable and unaffected by this method call.
513      *
514      * @return this date as a datetime at midnight
515      */

516     public DateTime toDateTimeAtMidnight() {
517         return toDateTimeAtMidnight(null);
518     }
519
520     /**
521      * Converts this LocalDate to a full datetime at midnight using the
522      * specified time zone.
523      * <p>
524      * This method uses the chronology from this instance plus the time zone
525      * specified.
526      * <p>
527      * This instance is immutable and unaffected by this method call.
528      *
529      * @param zone the zone to use, null means default zone
530      * @return this date as a datetime at midnight
531      */

532     public DateTime toDateTimeAtMidnight(DateTimeZone zone) {
533         zone = DateTimeUtils.getZone(zone);
534         Chronology chrono = getChronology().withZone(zone);
535         return new DateTime(getYear(), getMonthOfYear(), getDayOfMonth(), 0, 0, 0, 0, chrono);
536     }
537
538     //-----------------------------------------------------------------------
539
/**
540      * Converts this LocalDate to a full datetime using the default time zone
541      * setting the date fields from this instance and the time fields from
542      * the current time.
543      * <p>
544      * This instance is immutable and unaffected by this method call.
545      *
546      * @return this date as a datetime with the time as the current time
547      */

548     public DateTime toDateTimeAtCurrentTime() {
549         return toDateTimeAtCurrentTime(null);
550     }
551
552     /**
553      * Converts this LocalDate to a full datetime using the specified time zone
554      * setting the date fields from this instance and the time fields from
555      * the current time.
556      * <p>
557      * This method uses the chronology from this instance plus the time zone
558      * specified.
559      * <p>
560      * This instance is immutable and unaffected by this method call.
561      *
562      * @param zone the zone to use, null means default zone
563      * @return this date as a datetime with the time as the current time
564      */

565     public DateTime toDateTimeAtCurrentTime(DateTimeZone zone) {
566         zone = DateTimeUtils.getZone(zone);
567         Chronology chrono = getChronology().withZone(zone);
568         long instantMillis = DateTimeUtils.currentTimeMillis();
569         long resolved = chrono.set(this, instantMillis);
570         return new DateTime(resolved, chrono);
571     }
572
573     //-----------------------------------------------------------------------
574
/**
575      * Converts this LocalDate to a DateMidnight in the default time zone.
576      * <p>
577      * This instance is immutable and unaffected by this method call.
578      *
579      * @return the DateMidnight instance in the default zone
580      */

581     public DateMidnight toDateMidnight() {
582         return toDateMidnight(null);
583     }
584
585     /**
586      * Converts this LocalDate to a DateMidnight.
587      * <p>
588      * This instance is immutable and unaffected by this method call.
589      *
590      * @param zone the zone to get the DateMidnight in, null means default zone
591      * @return the DateMidnight instance
592      */

593     public DateMidnight toDateMidnight(DateTimeZone zone) {
594         zone = DateTimeUtils.getZone(zone);
595         Chronology chrono = getChronology().withZone(zone);
596         return new DateMidnight(getYear(), getMonthOfYear(), getDayOfMonth(), chrono);
597     }
598
599     //-----------------------------------------------------------------------
600
/**
601      * Converts this object to a DateTime using a LocalTime to fill in the
602      * missing fields and using the default time zone.
603      * <p>
604      * The resulting chronology is determined by the chronology of this
605      * LocalDate. The chronology of the time must match.
606      * If the time is null, the current time in the date's chronology is used.
607      * <p>
608      * This instance is immutable and unaffected by this method call.
609      *
610      * @param time the time of day to use, null means current time
611      * @return the DateTime instance
612      * @throws IllegalArgumentException if the chronology of the time does not match
613      */

614     public DateTime toDateTime(LocalTime time) {
615         return toDateTime(time, null);
616     }
617
618     /**
619      * Converts this object to a DateTime using a LocalTime to fill in the
620      * missing fields.
621      * <p>
622      * The resulting chronology is determined by the chronology of this
623      * LocalDate plus the time zone. The chronology of the time must match.
624      * If the time is null, the current time in the date's chronology is used.
625      * <p>
626      * This instance is immutable and unaffected by this method call.
627      *
628      * @param time the time of day to use, null means current time
629      * @param zone the zone to get the DateTime in, null means default
630      * @return the DateTime instance
631      * @throws IllegalArgumentException if the chronology of the time does not match
632      */

633     public DateTime toDateTime(LocalTime time, DateTimeZone zone) {
634         if (time != null && getChronology() != time.getChronology()) {
635             throw new IllegalArgumentException JavaDoc("The chronology of the time does not match");
636         }
637         Chronology chrono = getChronology().withZone(zone);
638         long instant = DateTimeUtils.currentTimeMillis();
639         instant = chrono.set(this, instant);
640         if (time != null) {
641             instant = chrono.set(time, instant);
642         }
643         return new DateTime(instant, chrono);
644     }
645
646     //-----------------------------------------------------------------------
647
/**
648      * Converts this object to an Interval representing the whole day
649      * in the default time zone.
650      * <p>
651      * This instance is immutable and unaffected by this method call.
652      *
653      * @return a interval over the day
654      */

655     public Interval toInterval() {
656         return toInterval(null);
657     }
658
659     /**
660      * Converts this object to an Interval representing the whole day.
661      * <p>
662      * This instance is immutable and unaffected by this method call.
663      *
664      * @param zone the zone to get the Interval in, null means default
665      * @return a interval over the day
666      */

667     public Interval toInterval(DateTimeZone zone) {
668         zone = DateTimeUtils.getZone(zone);
669         return toDateMidnight(zone).toInterval();
670     }
671
672     //-----------------------------------------------------------------------
673
/**
674      * Returns a copy of this date with different local millis.
675      * <p>
676      * The returned object will be a new instance of the same type.
677      * Only the millis will change, the chronology is kept.
678      * The returned object will be either be a new instance or <code>this</code>.
679      *
680      * @param newMillis the new millis, from 1970-01-01T00:00:00
681      * @return a copy of this date with different millis
682      */

683     LocalDate withLocalMillis(long newMillis) {
684         newMillis = iChronology.dayOfMonth().roundFloor(newMillis);
685         return (newMillis == getLocalMillis() ? this : new LocalDate(newMillis, getChronology()));
686     }
687
688     //-----------------------------------------------------------------------
689
/**
690      * Returns a copy of this date with the partial set of fields replacing
691      * those from this instance.
692      * <p>
693      * For example, if the partial contains a year and a month then those two
694      * fields will be changed in the returned instance.
695      * Unsupported fields are ignored.
696      * If the partial is null, then <code>this</code> is returned.
697      *
698      * @param partial the partial set of fields to apply to this date, null ignored
699      * @return a copy of this date with a different set of fields
700      * @throws IllegalArgumentException if any value is invalid
701      */

702     public LocalDate withFields(ReadablePartial partial) {
703         if (partial == null) {
704             return this;
705         }
706         return withLocalMillis(getChronology().set(partial, getLocalMillis()));
707     }
708
709     /**
710      * Returns a copy of this date with the specified field set to a new value.
711      * <p>
712      * For example, if the field type is <code>monthOfYear</code> then the
713      * month of year field will be changed in the returned instance.
714      * If the field type is null, then <code>this</code> is returned.
715      * <p>
716      * These two lines are equivalent:
717      * <pre>
718      * LocalDate updated = dt.withDayOfMonth(6);
719      * LocalDate updated = dt.withField(DateTimeFieldType.dayOfMonth(), 6);
720      * </pre>
721      *
722      * @param fieldType the field type to set, not null
723      * @param value the value to set
724      * @return a copy of this date with the field set
725      * @throws IllegalArgumentException if the field is null or unsupported
726      */

727     public LocalDate withField(DateTimeFieldType fieldType, int value) {
728         if (fieldType == null) {
729             throw new IllegalArgumentException JavaDoc("Field must not be null");
730         }
731         if (isSupported(fieldType) == false) {
732             throw new IllegalArgumentException JavaDoc("Field '" + fieldType + "' is not supported");
733         }
734         long instant = fieldType.getField(getChronology()).set(getLocalMillis(), value);
735         return withLocalMillis(instant);
736     }
737
738     /**
739      * Returns a copy of this date with the value of the specified field increased.
740      * <p>
741      * If the addition is zero or the field is null, then <code>this</code> is returned.
742      * <p>
743      * These three lines are equivalent:
744      * <pre>
745      * LocalDate added = dt.withFieldAdded(DurationFieldType.years(), 6);
746      * LocalDate added = dt.plusYears(6);
747      * LocalDate added = dt.plus(Period.years(6));
748      * </pre>
749      *
750      * @param fieldType the field type to add to, not null
751      * @param amount the amount to add
752      * @return a copy of this date with the field updated
753      * @throws IllegalArgumentException if the field is null or unsupported
754      * @throws ArithmeticException if the result exceeds the internal capacity
755      */

756     public LocalDate withFieldAdded(DurationFieldType fieldType, int amount) {
757         if (fieldType == null) {
758             throw new IllegalArgumentException JavaDoc("Field must not be null");
759         }
760         if (isSupported(fieldType) == false) {
761             throw new IllegalArgumentException JavaDoc("Field '" + fieldType + "' is not supported");
762         }
763         if (amount == 0) {
764             return this;
765         }
766         long instant = fieldType.getField(getChronology()).add(getLocalMillis(), amount);
767         return withLocalMillis(instant);
768     }
769
770     //-----------------------------------------------------------------------
771
/**
772      * Returns a copy of this date with the specified period added.
773      * <p>
774      * If the addition is zero, then <code>this</code> is returned.
775      * <p>
776      * This method is typically used to add multiple copies of complex
777      * period instances. Adding one field is best achieved using methods
778      * like {@link #withFieldAdded(DurationFieldType, int)}
779      * or {@link #plusYears(int)}.
780      * <p>
781      * Unsupported time fields are ignored, thus adding a period of 24 hours
782      * will not have any effect.
783      *
784      * @param period the period to add to this one, null means zero
785      * @param scalar the amount of times to add, such as -1 to subtract once
786      * @return a copy of this date with the period added
787      * @throws ArithmeticException if the result exceeds the internal capacity
788      */

789     public LocalDate withPeriodAdded(ReadablePeriod period, int scalar) {
790         if (period == null || scalar == 0) {
791             return this;
792         }
793         long instant = getLocalMillis();
794         Chronology chrono = getChronology();
795         for (int i = 0; i < period.size(); i++) {
796             long value = FieldUtils.safeMultiply(period.getValue(i), scalar);
797             DurationFieldType type = period.getFieldType(i);
798             if (isSupported(type)) {
799                 instant = type.getField(chrono).add(instant, value);
800             }
801         }
802         return withLocalMillis(instant);
803     }
804
805     //-----------------------------------------------------------------------
806
/**
807      * Returns a copy of this date with the specified period added.
808      * <p>
809      * If the amount is zero or null, then <code>this</code> is returned.
810      * <p>
811      * This method is typically used to add complex period instances.
812      * Adding one field is best achieved using methods
813      * like {@link #plusYears(int)}.
814      * <p>
815      * Unsupported time fields are ignored, thus adding a period of 24 hours
816      * will not have any effect.
817      *
818      * @param period the period to add to this one, null means zero
819      * @return a copy of this date with the period added
820      * @throws ArithmeticException if the result exceeds the internal capacity
821      */

822     public LocalDate plus(ReadablePeriod period) {
823         return withPeriodAdded(period, 1);
824     }
825
826     //-----------------------------------------------------------------------
827
/**
828      * Returns a copy of this date plus the specified number of years.
829      * <p>
830      * This LocalDate instance is immutable and unaffected by this method call.
831      * <p>
832      * The following three lines are identical in effect:
833      * <pre>
834      * LocalDate added = dt.plusYears(6);
835      * LocalDate added = dt.plus(Period.years(6));
836      * LocalDate added = dt.withFieldAdded(DurationFieldType.years(), 6);
837      * </pre>
838      *
839      * @param years the amount of years to add, may be negative
840      * @return the new LocalDate plus the increased years
841      */

842     public LocalDate plusYears(int years) {
843         if (years == 0) {
844             return this;
845         }
846         long instant = getChronology().years().add(getLocalMillis(), years);
847         return withLocalMillis(instant);
848     }
849
850     /**
851      * Returns a copy of this date plus the specified number of months.
852      * <p>
853      * This LocalDate instance is immutable and unaffected by this method call.
854      * <p>
855      * The following three lines are identical in effect:
856      * <pre>
857      * LocalDate added = dt.plusMonths(6);
858      * LocalDate added = dt.plus(Period.months(6));
859      * LocalDate added = dt.withFieldAdded(DurationFieldType.months(), 6);
860      * </pre>
861      *
862      * @param months the amount of months to add, may be negative
863      * @return the new LocalDate plus the increased months
864      */

865     public LocalDate plusMonths(int months) {
866         if (months == 0) {
867             return this;
868         }
869         long instant = getChronology().months().add(getLocalMillis(), months);
870         return withLocalMillis(instant);
871     }
872
873     /**
874      * Returns a copy of this date plus the specified number of weeks.
875      * <p>
876      * This LocalDate instance is immutable and unaffected by this method call.
877      * <p>
878      * The following three lines are identical in effect:
879      * <pre>
880      * LocalDate added = dt.plusWeeks(6);
881      * LocalDate added = dt.plus(Period.weeks(6));
882      * LocalDate added = dt.withFieldAdded(DurationFieldType.weeks(), 6);
883      * </pre>
884      *
885      * @param weeks the amount of weeks to add, may be negative
886      * @return the new LocalDate plus the increased weeks
887      */

888     public LocalDate plusWeeks(int weeks) {
889         if (weeks == 0) {
890             return this;
891         }
892         long instant = getChronology().weeks().add(getLocalMillis(), weeks);
893         return withLocalMillis(instant);
894     }
895
896     /**
897      * Returns a copy of this date plus the specified number of days.
898      * <p>
899      * This LocalDate instance is immutable and unaffected by this method call.
900      * <p>
901      * The following three lines are identical in effect:
902      * <pre>
903      * LocalDate added = dt.plusDays(6);
904      * LocalDate added = dt.plus(Period.days(6));
905      * LocalDate added = dt.withFieldAdded(DurationFieldType.days(), 6);
906      * </pre>
907      *
908      * @param days the amount of days to add, may be negative
909      * @return the new LocalDate plus the increased days
910      */

911     public LocalDate plusDays(int days) {
912         if (days == 0) {
913             return this;
914         }
915         long instant = getChronology().days().add(getLocalMillis(), days);
916         return withLocalMillis(instant);
917     }
918
919     //-----------------------------------------------------------------------
920
/**
921      * Returns a copy of this date with the specified period taken away.
922      * <p>
923      * If the amount is zero or null, then <code>this</code> is returned.
924      * <p>
925      * This method is typically used to subtract complex period instances.
926      * Subtracting one field is best achieved using methods
927      * like {@link #minusYears(int)}.
928      * <p>
929      * Unsupported time fields are ignored, thus subtracting a period of 24 hours
930      * will not have any effect.
931      *
932      * @param period the period to reduce this instant by
933      * @return a copy of this LocalDate with the period taken away
934      * @throws ArithmeticException if the result exceeds the internal capacity
935      */

936     public LocalDate minus(ReadablePeriod period) {
937         return withPeriodAdded(period, -1);
938     }
939
940     //-----------------------------------------------------------------------
941
/**
942      * Returns a copy of this date minus the specified number of years.
943      * <p>
944      * This LocalDate instance is immutable and unaffected by this method call.
945      * <p>
946      * The following three lines are identical in effect:
947      * <pre>
948      * LocalDate subtracted = dt.minusYears(6);
949      * LocalDate subtracted = dt.minus(Period.years(6));
950      * LocalDate subtracted = dt.withFieldAdded(DurationFieldType.years(), -6);
951      * </pre>
952      *
953      * @param years the amount of years to subtract, may be negative
954      * @return the new LocalDate minus the increased years
955      */

956     public LocalDate minusYears(int years) {
957         if (years == 0) {
958             return this;
959         }
960         long instant = getChronology().years().subtract(getLocalMillis(), years);
961         return withLocalMillis(instant);
962     }
963
964     /**
965      * Returns a copy of this date minus the specified number of months.
966      * <p>
967      * This LocalDate instance is immutable and unaffected by this method call.
968      * <p>
969      * The following three lines are identical in effect:
970      * <pre>
971      * LocalDate subtracted = dt.minusMonths(6);
972      * LocalDate subtracted = dt.minus(Period.months(6));
973      * LocalDate subtracted = dt.withFieldAdded(DurationFieldType.months(), -6);
974      * </pre>
975      *
976      * @param months the amount of months to subtract, may be negative
977      * @return the new LocalDate minus the increased months
978      */

979     public LocalDate minusMonths(int months) {
980         if (months == 0) {
981             return this;
982         }
983         long instant = getChronology().months().subtract(getLocalMillis(), months);
984         return withLocalMillis(instant);
985     }
986
987     /**
988      * Returns a copy of this date minus the specified number of weeks.
989      * <p>
990      * This LocalDate instance is immutable and unaffected by this method call.
991      * <p>
992      * The following three lines are identical in effect:
993      * <pre>
994      * LocalDate subtracted = dt.minusWeeks(6);
995      * LocalDate subtracted = dt.minus(Period.weeks(6));
996      * LocalDate subtracted = dt.withFieldAdded(DurationFieldType.weeks(), -6);
997      * </pre>
998      *
999      * @param weeks the amount of weeks to subtract, may be negative
1000     * @return the new LocalDate minus the increased weeks
1001     */

1002    public LocalDate minusWeeks(int weeks) {
1003        if (weeks == 0) {
1004            return this;
1005        }
1006        long instant = getChronology().weeks().subtract(getLocalMillis(), weeks);
1007        return withLocalMillis(instant);
1008    }
1009
1010    /**
1011     * Returns a copy of this date minus the specified number of days.
1012     * <p>
1013     * This LocalDate instance is immutable and unaffected by this method call.
1014     * <p>
1015     * The following three lines are identical in effect:
1016     * <pre>
1017     * LocalDate subtracted = dt.minusDays(6);
1018     * LocalDate subtracted = dt.minus(Period.days(6));
1019     * LocalDate subtracted = dt.withFieldAdded(DurationFieldType.days(), -6);
1020     * </pre>
1021     *
1022     * @param days the amount of days to subtract, may be negative
1023     * @return the new LocalDate minus the increased days
1024     */

1025    public LocalDate minusDays(int days) {
1026        if (days == 0) {
1027            return this;
1028        }
1029        long instant = getChronology().days().subtract(getLocalMillis(), days);
1030        return withLocalMillis(instant);
1031    }
1032
1033    //-----------------------------------------------------------------------
1034
/**
1035     * Gets the property object for the specified type, which contains many
1036     * useful methods.
1037     *
1038     * @param fieldType the field type to get the chronology for
1039     * @return the property object
1040     * @throws IllegalArgumentException if the field is null or unsupported
1041     */

1042    public Property property(DateTimeFieldType fieldType) {
1043        if (fieldType == null) {
1044            throw new IllegalArgumentException JavaDoc("The DateTimeFieldType must not be null");
1045        }
1046        if (isSupported(fieldType) == false) {
1047            throw new IllegalArgumentException JavaDoc("Field '" + fieldType + "' is not supported");
1048        }
1049        return new Property(this, fieldType.getField(getChronology()));
1050    }
1051
1052    //-----------------------------------------------------------------------
1053
/**
1054     * Get the era field value.
1055     *
1056     * @return the era
1057     */

1058    public int getEra() {
1059        return getChronology().era().get(getLocalMillis());
1060    }
1061
1062    /**
1063     * Get the year of era field value.
1064     *
1065     * @return the year of era
1066     */

1067    public int getCenturyOfEra() {
1068        return getChronology().centuryOfEra().get(getLocalMillis());
1069    }
1070
1071    /**
1072     * Get the year of era field value.
1073     *
1074     * @return the year of era
1075     */

1076    public int getYearOfEra() {
1077        return getChronology().yearOfEra().get(getLocalMillis());
1078    }
1079
1080    /**
1081     * Get the year of century field value.
1082     *
1083     * @return the year of century
1084     */

1085    public int getYearOfCentury() {
1086        return getChronology().yearOfCentury().get(getLocalMillis());
1087    }
1088
1089    /**
1090     * Get the year field value.
1091     *
1092     * @return the year
1093     */

1094    public int getYear() {
1095        return getChronology().year().get(getLocalMillis());
1096    }
1097
1098    /**
1099     * Get the weekyear field value.
1100     * <p>
1101     * The weekyear is the year that matches with the weekOfWeekyear field.
1102     * In the standard ISO8601 week algorithm, the first week of the year
1103     * is that in which at least 4 days are in the year. As a result of this
1104     * definition, day 1 of the first week may be in the previous year.
1105     * The weekyear allows you to query the effective year for that day.
1106     *
1107     * @return the weekyear
1108     */

1109    public int getWeekyear() {
1110        return getChronology().weekyear().get(getLocalMillis());
1111    }
1112
1113    /**
1114     * Get the month of year field value.
1115     *
1116     * @return the month of year
1117     */

1118    public int getMonthOfYear() {
1119        return getChronology().monthOfYear().get(getLocalMillis());
1120    }
1121
1122    /**
1123     * Get the week of weekyear field value.
1124     *
1125     * @return the week of a week based year
1126     */

1127    public int getWeekOfWeekyear() {
1128        return getChronology().weekOfWeekyear().get(getLocalMillis());
1129    }
1130
1131    /**
1132     * Get the day of year field value.
1133     *
1134     * @return the day of year
1135     */

1136    public int getDayOfYear() {
1137        return getChronology().dayOfYear().get(getLocalMillis());
1138    }
1139
1140    /**
1141     * Get the day of month field value.
1142     * <p>
1143     * The values for the day of month are defined in {@link org.joda.time.DateTimeConstants}.
1144     *
1145     * @return the day of month
1146     */

1147    public int getDayOfMonth() {
1148        return getChronology().dayOfMonth().get(getLocalMillis());
1149    }
1150
1151    /**
1152     * Get the day of week field value.
1153     * <p>
1154     * The values for the day of week are defined in {@link org.joda.time.DateTimeConstants}.
1155     *
1156     * @return the day of week
1157     */

1158    public int getDayOfWeek() {
1159        return getChronology().dayOfWeek().get(getLocalMillis());
1160    }
1161
1162    //-----------------------------------------------------------------------
1163
/**
1164     * Returns a copy of this date with the era field updated.
1165     * <p>
1166     * LocalDate is immutable, so there are no set methods.
1167     * Instead, this method returns a new instance with the value of
1168     * era changed.
1169     *
1170     * @param era the era to set
1171     * @return a copy of this object with the field set
1172     * @throws IllegalArgumentException if the value is invalid
1173     */

1174    public LocalDate withEra(int era) {
1175        return withLocalMillis(getChronology().era().set(getLocalMillis(), era));
1176    }
1177
1178    /**
1179     * Returns a copy of this date with the century of era field updated.
1180     * <p>
1181     * LocalDate is immutable, so there are no set methods.
1182     * Instead, this method returns a new instance with the value of
1183     * century of era changed.
1184     *
1185     * @param centuryOfEra the centurey of era to set
1186     * @return a copy of this object with the field set
1187     * @throws IllegalArgumentException if the value is invalid
1188     */

1189    public LocalDate withCenturyOfEra(int centuryOfEra) {
1190        return withLocalMillis(getChronology().centuryOfEra().set(getLocalMillis(), centuryOfEra));
1191    }
1192
1193    /**
1194     * Returns a copy of this date with the year of era field updated.
1195     * <p>
1196     * LocalDate is immutable, so there are no set methods.
1197     * Instead, this method returns a new instance with the value of
1198     * year of era changed.
1199     *
1200     * @param yearOfEra the year of era to set
1201     * @return a copy of this object with the field set
1202     * @throws IllegalArgumentException if the value is invalid
1203     */

1204    public LocalDate withYearOfEra(int yearOfEra) {
1205        return withLocalMillis(getChronology().yearOfEra().set(getLocalMillis(), yearOfEra));
1206    }
1207
1208    /**
1209     * Returns a copy of this date with the year of century field updated.
1210     * <p>
1211     * LocalDate is immutable, so there are no set methods.
1212     * Instead, this method returns a new instance with the value of
1213     * year of century changed.
1214     *
1215     * @param yearOfCentury the year of century to set
1216     * @return a copy of this object with the field set
1217     * @throws IllegalArgumentException if the value is invalid
1218     */

1219    public LocalDate withYearOfCentury(int yearOfCentury) {
1220        return withLocalMillis(getChronology().yearOfCentury().set(getLocalMillis(), yearOfCentury));
1221    }
1222
1223    /**
1224     * Returns a copy of this date with the year field updated.
1225     * <p>
1226     * LocalDate is immutable, so there are no set methods.
1227     * Instead, this method returns a new instance with the value of
1228     * year changed.
1229     *
1230     * @param year the year to set
1231     * @return a copy of this object with the field set
1232     * @throws IllegalArgumentException if the value is invalid
1233     */

1234    public LocalDate withYear(int year) {
1235        return withLocalMillis(getChronology().year().set(getLocalMillis(), year));
1236    }
1237
1238    /**
1239     * Returns a copy of this date with the weekyear field updated.
1240     * <p>
1241     * LocalDate is immutable, so there are no set methods.
1242     * Instead, this method returns a new instance with the value of
1243     * weekyear changed.
1244     *
1245     * @param weekyear the weekyear to set
1246     * @return a copy of this object with the field set
1247     * @throws IllegalArgumentException if the value is invalid
1248     */

1249    public LocalDate withWeekyear(int weekyear) {
1250        return withLocalMillis(getChronology().weekyear().set(getLocalMillis(), weekyear));
1251    }
1252
1253    /**
1254     * Returns a copy of this date with the month of year field updated.
1255     * <p>
1256     * LocalDate is immutable, so there are no set methods.
1257     * Instead, this method returns a new instance with the value of
1258     * month of year changed.
1259     *
1260     * @param monthOfYear the month of year to set
1261     * @return a copy of this object with the field set
1262     * @throws IllegalArgumentException if the value is invalid
1263     */

1264    public LocalDate withMonthOfYear(int monthOfYear) {
1265        return withLocalMillis(getChronology().monthOfYear().set(getLocalMillis(), monthOfYear));
1266    }
1267
1268    /**
1269     * Returns a copy of this date with the week of weekyear field updated.
1270     * <p>
1271     * LocalDate is immutable, so there are no set methods.
1272     * Instead, this method returns a new instance with the value of
1273     * week of weekyear changed.
1274     *
1275     * @param weekOfWeekyear the week of weekyear to set
1276     * @return a copy of this object with the field set
1277     * @throws IllegalArgumentException if the value is invalid
1278     */

1279    public LocalDate withWeekOfWeekyear(int weekOfWeekyear) {
1280        return withLocalMillis(getChronology().weekOfWeekyear().set(getLocalMillis(), weekOfWeekyear));
1281    }
1282
1283    /**
1284     * Returns a copy of this date with the day of year field updated.
1285     * <p>
1286     * LocalDate is immutable, so there are no set methods.
1287     * Instead, this method returns a new instance with the value of
1288     * day of year changed.
1289     *
1290     * @param dayOfYear the day of year to set
1291     * @return a copy of this object with the field set
1292     * @throws IllegalArgumentException if the value is invalid
1293     */

1294    public LocalDate withDayOfYear(int dayOfYear) {
1295        return withLocalMillis(getChronology().dayOfYear().set(getLocalMillis(), dayOfYear));
1296    }
1297
1298    /**
1299     * Returns a copy of this date with the day of month field updated.
1300     * <p>
1301     * LocalDate is immutable, so there are no set methods.
1302     * Instead, this method returns a new instance with the value of
1303     * day of month changed.
1304     *
1305     * @param dayOfMonth the day of month to set
1306     * @return a copy of this object with the field set
1307     * @throws IllegalArgumentException if the value is invalid
1308     */

1309    public LocalDate withDayOfMonth(int dayOfMonth) {
1310        return withLocalMillis(getChronology().dayOfMonth().set(getLocalMillis(), dayOfMonth));
1311    }
1312
1313    /**
1314     * Returns a copy of this date with the day of week field updated.
1315     * <p>
1316     * LocalDate is immutable, so there are no set methods.
1317     * Instead, this method returns a new instance with the value of
1318     * day of week changed.
1319     *
1320     * @param dayOfWeek the day of week to set
1321     * @return a copy of this object with the field set
1322     * @throws IllegalArgumentException if the value is invalid
1323     */

1324    public LocalDate withDayOfWeek(int dayOfWeek) {
1325        return withLocalMillis(getChronology().dayOfWeek().set(getLocalMillis(), dayOfWeek));
1326    }
1327
1328    //-----------------------------------------------------------------------
1329
/**
1330     * Get the era property which provides access to advanced functionality.
1331     *
1332     * @return the era property
1333     */

1334    public Property era() {
1335        return new Property(this, getChronology().era());
1336    }
1337
1338    /**
1339     * Get the century of era property which provides access to advanced functionality.
1340     *
1341     * @return the year of era property
1342     */

1343    public Property centuryOfEra() {
1344        return new Property(this, getChronology().centuryOfEra());
1345    }
1346
1347    /**
1348     * Get the year of century property which provides access to advanced functionality.
1349     *
1350     * @return the year of era property
1351     */

1352    public Property yearOfCentury() {
1353        return new Property(this, getChronology().yearOfCentury());
1354    }
1355
1356    /**
1357     * Get the year of era property which provides access to advanced functionality.
1358     *
1359     * @return the year of era property
1360     */

1361    public Property yearOfEra() {
1362        return new Property(this, getChronology().yearOfEra());
1363    }
1364
1365    /**
1366     * Get the year property which provides access to advanced functionality.
1367     *
1368     * @return the year property
1369     */

1370    public Property year() {
1371        return new Property(this, getChronology().year());
1372    }
1373
1374    /**
1375     * Get the weekyear property which provides access to advanced functionality.
1376     *
1377     * @return the weekyear property
1378     */

1379    public Property weekyear() {
1380        return new Property(this, getChronology().weekyear());
1381    }
1382
1383    /**
1384     * Get the month of year property which provides access to advanced functionality.
1385     *
1386     * @return the month of year property
1387     */

1388    public Property monthOfYear() {
1389        return new Property(this, getChronology().monthOfYear());
1390    }
1391
1392    /**
1393     * Get the week of a week based year property which provides access to advanced functionality.
1394     *
1395     * @return the week of a week based year property
1396     */

1397    public Property weekOfWeekyear() {
1398        return new Property(this, getChronology().weekOfWeekyear());
1399    }
1400
1401    /**
1402     * Get the day of year property which provides access to advanced functionality.
1403     *
1404     * @return the day of year property
1405     */

1406    public Property dayOfYear() {
1407        return new Property(this, getChronology().dayOfYear());
1408    }
1409
1410    /**
1411     * Get the day of month property which provides access to advanced functionality.
1412     *
1413     * @return the day of month property
1414     */

1415    public Property dayOfMonth() {
1416        return new Property(this, getChronology().dayOfMonth());
1417    }
1418
1419    /**
1420     * Get the day of week property which provides access to advanced functionality.
1421     *
1422     * @return the day of week property
1423     */

1424    public Property dayOfWeek() {
1425        return new Property(this, getChronology().dayOfWeek());
1426    }
1427
1428    //-----------------------------------------------------------------------
1429
/**
1430     * Output the date time in ISO8601 format (yyyy-MM-dd).
1431     *
1432     * @return ISO8601 time formatted string.
1433     */

1434    public String JavaDoc toString() {
1435        return ISODateTimeFormat.date().print(this);
1436    }
1437
1438    /**
1439     * Output the date using the specified format pattern.
1440     *
1441     * @param pattern the pattern specification, null means use <code>toString</code>
1442     * @see org.joda.time.format.DateTimeFormat
1443     */

1444    public String JavaDoc toString(String JavaDoc pattern) {
1445        if (pattern == null) {
1446            return toString();
1447        }
1448        return DateTimeFormat.forPattern(pattern).print(this);
1449    }
1450
1451    /**
1452     * Output the date using the specified format pattern.
1453     *
1454     * @param pattern the pattern specification, null means use <code>toString</code>
1455     * @param locale Locale to use, null means default
1456     * @see org.joda.time.format.DateTimeFormat
1457     */

1458    public String JavaDoc toString(String JavaDoc pattern, Locale JavaDoc locale) throws IllegalArgumentException JavaDoc {
1459        if (pattern == null) {
1460            return toString();
1461        }
1462        return DateTimeFormat.forPattern(pattern).withLocale(locale).print(this);
1463    }
1464
1465    //-----------------------------------------------------------------------
1466
/**
1467     * LocalDate.Property binds a LocalDate to a DateTimeField allowing
1468     * powerful datetime functionality to be easily accessed.
1469     * <p>
1470     * The simplest use of this class is as an alternative get method, here used to
1471     * get the year '1972' (as an int) and the month 'December' (as a String).
1472     * <pre>
1473     * LocalDate dt = new LocalDate(1972, 12, 3, 0, 0);
1474     * int year = dt.year().get();
1475     * String monthStr = dt.month().getAsText();
1476     * </pre>
1477     * <p>
1478     * Methods are also provided that allow date modification. These return
1479     * new instances of LocalDate - they do not modify the original. The example
1480     * below yields two independent immutable date objects 20 years apart.
1481     * <pre>
1482     * LocalDate dt = new LocalDate(1972, 12, 3);
1483     * LocalDate dt1920 = dt.year().setCopy(1920);
1484     * </pre>
1485     * <p>
1486     * LocalDate.Property itself is thread-safe and immutable, as well as the
1487     * LocalDate being operated on.
1488     *
1489     * @author Stephen Colebourne
1490     * @author Brian S O'Neill
1491     * @since 1.3
1492     */

1493    public static final class Property extends AbstractReadableInstantFieldProperty {
1494        
1495        /** Serialization version */
1496        private static final long serialVersionUID = -3193829732634L;
1497        
1498        /** The instant this property is working against */
1499        private transient LocalDate iInstant;
1500        /** The field this property is working against */
1501        private transient DateTimeField iField;
1502        
1503        /**
1504         * Constructor.
1505         *
1506         * @param instant the instant to set
1507         * @param field the field to use
1508         */

1509        Property(LocalDate instant, DateTimeField field) {
1510            super();
1511            iInstant = instant;
1512            iField = field;
1513        }
1514        
1515        /**
1516         * Writes the property in a safe serialization format.
1517         */

1518        private void writeObject(ObjectOutputStream JavaDoc oos) throws IOException JavaDoc {
1519            oos.writeObject(iInstant);
1520            oos.writeObject(iField.getType());
1521        }
1522
1523        /**
1524         * Reads the property from a safe serialization format.
1525         */

1526        private void readObject(ObjectInputStream JavaDoc oos) throws IOException JavaDoc, ClassNotFoundException JavaDoc {
1527            iInstant = (LocalDate) oos.readObject();
1528            DateTimeFieldType type = (DateTimeFieldType) oos.readObject();
1529            iField = type.getField(iInstant.getChronology());
1530        }
1531
1532        //-----------------------------------------------------------------------
1533
/**
1534         * Gets the field being used.
1535         *
1536         * @return the field
1537         */

1538        public DateTimeField getField() {
1539            return iField;
1540        }
1541        
1542        /**
1543         * Gets the milliseconds of the date that this property is linked to.
1544         *
1545         * @return the milliseconds
1546         */

1547        protected long getMillis() {
1548            return iInstant.getLocalMillis();
1549        }
1550        
1551        /**
1552         * Gets the chronology of the datetime that this property is linked to.
1553         *
1554         * @return the chronology
1555         * @since 1.4
1556         */

1557        protected Chronology getChronology() {
1558            return iInstant.getChronology();
1559        }
1560        
1561        /**
1562         * Gets the LocalDate object linked to this property.
1563         *
1564         * @return the linked LocalDate
1565         */

1566        public LocalDate getLocalDate() {
1567            return iInstant;
1568        }
1569        
1570        //-----------------------------------------------------------------------
1571
/**
1572         * Adds to this field in a copy of this LocalDate.
1573         * <p>
1574         * The LocalDate attached to this property is unchanged by this call.
1575         *
1576         * @param value the value to add to the field in the copy
1577         * @return a copy of the LocalDate with the field value changed
1578         * @throws IllegalArgumentException if the value isn't valid
1579         */

1580        public LocalDate addToCopy(int value) {
1581            return iInstant.withLocalMillis(iField.add(iInstant.getLocalMillis(), value));
1582        }
1583        
1584        /**
1585         * Adds to this field, possibly wrapped, in a copy of this LocalDate.
1586         * A field wrapped operation only changes this field.
1587         * Thus 31st January addWrapField one day goes to the 1st January.
1588         * <p>
1589         * The LocalDate attached to this property is unchanged by this call.
1590         *
1591         * @param value the value to add to the field in the copy
1592         * @return a copy of the LocalDate with the field value changed
1593         * @throws IllegalArgumentException if the value isn't valid
1594         */

1595        public LocalDate addWrapFieldToCopy(int value) {
1596            return iInstant.withLocalMillis(iField.addWrapField(iInstant.getLocalMillis(), value));
1597        }
1598        
1599        //-----------------------------------------------------------------------
1600
/**
1601         * Sets this field in a copy of the LocalDate.
1602         * <p>
1603         * The LocalDate attached to this property is unchanged by this call.
1604         *
1605         * @param value the value to set the field in the copy to
1606         * @return a copy of the LocalDate with the field value changed
1607         * @throws IllegalArgumentException if the value isn't valid
1608         */

1609        public LocalDate setCopy(int value) {
1610            return iInstant.withLocalMillis(iField.set(iInstant.getLocalMillis(), value));
1611        }
1612        
1613        /**
1614         * Sets this field in a copy of the LocalDate to a parsed text value.
1615         * <p>
1616         * The LocalDate attached to this property is unchanged by this call.
1617         *
1618         * @param text the text value to set
1619         * @param locale optional locale to use for selecting a text symbol
1620         * @return a copy of the LocalDate with the field value changed
1621         * @throws IllegalArgumentException if the text value isn't valid
1622         */

1623        public LocalDate setCopy(String JavaDoc text, Locale JavaDoc locale) {
1624            return iInstant.withLocalMillis(iField.set(iInstant.getLocalMillis(), text, locale));
1625        }
1626        
1627        /**
1628         * Sets this field in a copy of the LocalDate to a parsed text value.
1629         * <p>
1630         * The LocalDate attached to this property is unchanged by this call.
1631         *
1632         * @param text the text value to set
1633         * @return a copy of the LocalDate with the field value changed
1634         * @throws IllegalArgumentException if the text value isn't valid
1635         */

1636        public LocalDate setCopy(String JavaDoc text) {
1637            return setCopy(text, null);
1638        }
1639        
1640        //-----------------------------------------------------------------------
1641
/**
1642         * Returns a new LocalDate with this field set to the maximum value
1643         * for this field.
1644         * <p>
1645         * This operation is useful for obtaining a LocalDate on the last day
1646         * of the month, as month lengths vary.
1647         * <pre>
1648         * LocalDate lastDayOfMonth = dt.dayOfMonth().withMaximumValue();
1649         * </pre>
1650         * <p>
1651         * The LocalDate attached to this property is unchanged by this call.
1652         *
1653         * @return a copy of the LocalDate with this field set to its maximum
1654         */

1655        public LocalDate withMaximumValue() {
1656            return setCopy(getMaximumValue());
1657        }
1658        
1659        /**
1660         * Returns a new LocalDate with this field set to the minimum value
1661         * for this field.
1662         * <p>
1663         * The LocalDate attached to this property is unchanged by this call.
1664         *
1665         * @return a copy of the LocalDate with this field set to its minimum
1666         */

1667        public LocalDate withMinimumValue() {
1668            return setCopy(getMinimumValue());
1669        }
1670        
1671        //-----------------------------------------------------------------------
1672
/**
1673         * Rounds to the lowest whole unit of this field on a copy of this
1674         * LocalDate.
1675         * <p>
1676         * For example, rounding floor on the hourOfDay field of a LocalDate
1677         * where the time is 10:30 would result in new LocalDate with the
1678         * time of 10:00.
1679         *
1680         * @return a copy of the LocalDate with the field value changed
1681         */

1682        public LocalDate roundFloorCopy() {
1683            return iInstant.withLocalMillis(iField.roundFloor(iInstant.getLocalMillis()));
1684        }
1685        
1686        /**
1687         * Rounds to the highest whole unit of this field on a copy of this
1688         * LocalDate.
1689         * <p>
1690         * For example, rounding floor on the hourOfDay field of a LocalDate
1691         * where the time is 10:30 would result in new LocalDate with the
1692         * time of 11:00.
1693         *
1694         * @return a copy of the LocalDate with the field value changed
1695         */

1696        public LocalDate roundCeilingCopy() {
1697            return iInstant.withLocalMillis(iField.roundCeiling(iInstant.getLocalMillis()));
1698        }
1699        
1700        /**
1701         * Rounds to the nearest whole unit of this field on a copy of this
1702         * LocalDate, favoring the floor if halfway.
1703         *
1704         * @return a copy of the LocalDate with the field value changed
1705         */

1706        public LocalDate roundHalfFloorCopy() {
1707            return iInstant.withLocalMillis(iField.roundHalfFloor(iInstant.getLocalMillis()));
1708        }
1709        
1710        /**
1711         * Rounds to the nearest whole unit of this field on a copy of this
1712         * LocalDate, favoring the ceiling if halfway.
1713         *
1714         * @return a copy of the LocalDate with the field value changed
1715         */

1716        public LocalDate roundHalfCeilingCopy() {
1717            return iInstant.withLocalMillis(iField.roundHalfCeiling(iInstant.getLocalMillis()));
1718        }
1719        
1720        /**
1721         * Rounds to the nearest whole unit of this field on a copy of this
1722         * LocalDate. If halfway, the ceiling is favored over the floor
1723         * only if it makes this field's value even.
1724         *
1725         * @return a copy of the LocalDate with the field value changed
1726         */

1727        public LocalDate roundHalfEvenCopy() {
1728            return iInstant.withLocalMillis(iField.roundHalfEven(iInstant.getLocalMillis()));
1729        }
1730    }
1731
1732}
1733
Popular Tags