KickJava   Java API By Example, From Geeks To Geeks.

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


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.Serializable JavaDoc;
19 import java.util.Calendar JavaDoc;
20 import java.util.Date JavaDoc;
21 import java.util.Locale JavaDoc;
22
23 import org.joda.time.base.BasePartial;
24 import org.joda.time.chrono.ISOChronology;
25 import org.joda.time.field.AbstractPartialFieldProperty;
26 import org.joda.time.field.FieldUtils;
27 import org.joda.time.format.ISODateTimeFormat;
28
29 /**
30  * YearMonthDay is an immutable partial supporting the year, monthOfYear
31  * and dayOfMonth fields.
32  * <p>
33  * NOTE: This class is effectively deprecated. New applications should
34  * use {@link LocalDate} which has a better internal implementation.
35  * This class has not yet been formally deprecated due to the large number
36  * of existing users.
37  * <p>
38  * NOTE: This class only supports the three fields listed above. Thus, you
39  * cannot query the dayOfWeek or centuryOfEra fields for example.
40  * The new <code>LocalDate</code> class removes this restriction.
41  * <p>
42  * Calculations on YearMonthDay are performed using a {@link Chronology}.
43  * This chronology is set to be in the UTC time zone for all calculations.
44  * <p>
45  * Each individual field can be queried in two ways:
46  * <ul>
47  * <li><code>getMonthOfYear()</code>
48  * <li><code>monthOfYear().get()</code>
49  * </ul>
50  * The second technique also provides access to other useful methods on the
51  * field:
52  * <ul>
53  * <li>numeric value - <code>monthOfYear().get()</code>
54  * <li>text value - <code>monthOfYear().getAsText()</code>
55  * <li>short text value - <code>monthOfYear().getAsShortText()</code>
56  * <li>maximum/minimum values - <code>monthOfYear().getMaximumValue()</code>
57  * <li>add/subtract - <code>monthOfYear().addToCopy()</code>
58  * <li>set - <code>monthOfYear().setCopy()</code>
59  * </ul>
60  * <p>
61  * YearMonthDay is thread-safe and immutable, provided that the Chronology is as well.
62  * All standard Chronology classes supplied are thread-safe and immutable.
63  *
64  * @author Stephen Colebourne
65  * @since 1.0
66  */

67 public final class YearMonthDay
68         extends BasePartial
69         implements ReadablePartial, Serializable JavaDoc {
70
71     /** Serialization version */
72     private static final long serialVersionUID = 797544782896179L;
73     /** The singleton set of field types */
74     private static final DateTimeFieldType[] FIELD_TYPES = new DateTimeFieldType[] {
75         DateTimeFieldType.year(),
76         DateTimeFieldType.monthOfYear(),
77         DateTimeFieldType.dayOfMonth(),
78     };
79
80     /** The index of the year field in the field array */
81     public static final int YEAR = 0;
82     /** The index of the monthOfYear field in the field array */
83     public static final int MONTH_OF_YEAR = 1;
84     /** The index of the dayOfMonth field in the field array */
85     public static final int DAY_OF_MONTH = 2;
86
87     //-----------------------------------------------------------------------
88
/**
89      * Constructs a YearMonthDay from a <code>java.util.Calendar</code>
90      * using exactly the same field values avoiding any time zone effects.
91      * <p>
92      * Each field is queried from the Calendar and assigned to the YearMonthDay.
93      * This is useful if you have been using the Calendar as a local date,
94      * ignoing the zone.
95      * <p>
96      * This factory method ignores the type of the calendar and always
97      * creates a YearMonthDay with ISO chronology. It is expected that you
98      * will only pass in instances of <code>GregorianCalendar</code> however
99      * this is not validated.
100      *
101      * @param calendar the Calendar to extract fields from
102      * @return the created YearMonthDay
103      * @throws IllegalArgumentException if the calendar is null
104      * @throws IllegalArgumentException if the date is invalid for the ISO chronology
105      * @since 1.2
106      */

107     public static YearMonthDay fromCalendarFields(Calendar JavaDoc calendar) {
108         if (calendar == null) {
109             throw new IllegalArgumentException JavaDoc("The calendar must not be null");
110         }
111         return new YearMonthDay(
112             calendar.get(Calendar.YEAR),
113             calendar.get(Calendar.MONTH) + 1,
114             calendar.get(Calendar.DAY_OF_MONTH)
115         );
116     }
117
118     /**
119      * Constructs a YearMonthDay from a <code>java.util.Date</code>
120      * using exactly the same field values avoiding any time zone effects.
121      * <p>
122      * Each field is queried from the Date and assigned to the YearMonthDay.
123      * This is useful if you have been using the Date as a local date,
124      * ignoing the zone.
125      * <p>
126      * This factory method always creates a YearMonthDay with ISO chronology.
127      *
128      * @param date the Date to extract fields from
129      * @return the created YearMonthDay
130      * @throws IllegalArgumentException if the calendar is null
131      * @throws IllegalArgumentException if the date is invalid for the ISO chronology
132      * @since 1.2
133      */

134     public static YearMonthDay fromDateFields(Date JavaDoc date) {
135         if (date == null) {
136             throw new IllegalArgumentException JavaDoc("The date must not be null");
137         }
138         return new YearMonthDay(
139             date.getYear() + 1900,
140             date.getMonth() + 1,
141             date.getDate()
142         );
143     }
144
145     //-----------------------------------------------------------------------
146
/**
147      * Constructs a YearMonthDay with the current date, using ISOChronology in
148      * the default zone to extract the fields.
149      * <p>
150      * The constructor uses the default time zone, resulting in the local time
151      * being initialised. Once the constructor is complete, all further calculations
152      * are performed without reference to a timezone (by switching to UTC).
153      */

154     public YearMonthDay() {
155         super();
156     }
157
158     /**
159      * Constructs a YearMonthDay with the current date, using ISOChronology in
160      * the specified zone to extract the fields.
161      * <p>
162      * The constructor uses the specified time zone to obtain the current date.
163      * Once the constructor is complete, all further calculations
164      * are performed without reference to a timezone (by switching to UTC).
165      *
166      * @param zone the zone to use, null means default zone
167      * @since 1.1
168      */

169     public YearMonthDay(DateTimeZone zone) {
170         super(ISOChronology.getInstance(zone));
171     }
172
173     /**
174      * Constructs a YearMonthDay with the current date, using the specified chronology
175      * and zone to extract the fields.
176      * <p>
177      * The constructor uses the time zone of the chronology specified.
178      * Once the constructor is complete, all further calculations are performed
179      * without reference to a timezone (by switching to UTC).
180      *
181      * @param chronology the chronology, null means ISOChronology in the default zone
182      */

183     public YearMonthDay(Chronology chronology) {
184         super(chronology);
185     }
186
187     /**
188      * Constructs a YearMonthDay extracting the partial fields from the specified
189      * milliseconds using the ISOChronology in the default zone.
190      * <p>
191      * The constructor uses the default time zone, resulting in the local time
192      * being initialised. Once the constructor is complete, all further calculations
193      * are performed without reference to a timezone (by switching to UTC).
194      *
195      * @param instant the milliseconds from 1970-01-01T00:00:00Z
196      */

197     public YearMonthDay(long instant) {
198         super(instant);
199     }
200
201     /**
202      * Constructs a YearMonthDay extracting the partial fields from the specified
203      * milliseconds using the chronology provided.
204      * <p>
205      * The constructor uses the time zone of the chronology specified.
206      * Once the constructor is complete, all further calculations are performed
207      * without reference to a timezone (by switching to UTC).
208      *
209      * @param instant the milliseconds from 1970-01-01T00:00:00Z
210      * @param chronology the chronology, null means ISOChronology in the default zone
211      */

212     public YearMonthDay(long instant, Chronology chronology) {
213         super(instant, chronology);
214     }
215
216     /**
217      * Constructs a YearMonthDay from an Object that represents a time.
218      * <p>
219      * The recognised object types are defined in
220      * {@link org.joda.time.convert.ConverterManager ConverterManager} and
221      * include ReadableInstant, String, Calendar and Date.
222      * The String formats are described by {@link ISODateTimeFormat#dateOptionalTimeParser()}.
223      * <p>
224      * The chronology used will be derived from the object, defaulting to ISO.
225      * <p>
226      * NOTE: Prior to v1.3 the string format was described by
227      * {@link ISODateTimeFormat#dateTimeParser()}. Time ony strings are now rejected.
228      *
229      * @param instant the datetime object, null means now
230      * @throws IllegalArgumentException if the instant is invalid
231      */

232     public YearMonthDay(Object JavaDoc instant) {
233         super(instant, null, ISODateTimeFormat.dateOptionalTimeParser());
234     }
235
236     /**
237      * Constructs a YearMonthDay from an Object that represents a time, using the
238      * specified chronology.
239      * <p>
240      * The recognised object types are defined in
241      * {@link org.joda.time.convert.ConverterManager ConverterManager} and
242      * include ReadableInstant, String, Calendar and Date.
243      * The String formats are described by {@link ISODateTimeFormat#dateOptionalTimeParser()}.
244      * <p>
245      * The constructor uses the time zone of the chronology specified.
246      * Once the constructor is complete, all further calculations are performed
247      * without reference to a timezone (by switching to UTC).
248      * The specified chronology overrides that of the object.
249      * <p>
250      * NOTE: Prior to v1.3 the string format was described by
251      * {@link ISODateTimeFormat#dateTimeParser()}. Time only strings are now rejected.
252      *
253      * @param instant the datetime object, null means now
254      * @param chronology the chronology, null means ISO default
255      * @throws IllegalArgumentException if the instant is invalid
256      */

257     public YearMonthDay(Object JavaDoc instant, Chronology chronology) {
258         super(instant, DateTimeUtils.getChronology(chronology), ISODateTimeFormat.dateOptionalTimeParser());
259     }
260
261     /**
262      * Constructs a YearMonthDay with specified time field values
263      * using <code>ISOChronology</code> in the default zone.
264      * <p>
265      * The constructor uses the no time zone initialising the fields as provided.
266      * Once the constructor is complete, all further calculations
267      * are performed without reference to a timezone (by switching to UTC).
268      *
269      * @param year the year
270      * @param monthOfYear the month of the year
271      * @param dayOfMonth the day of the month
272      */

273     public YearMonthDay(int year, int monthOfYear, int dayOfMonth) {
274         this(year, monthOfYear, dayOfMonth, null);
275     }
276
277     /**
278      * Constructs a YearMonthDay with specified time field values.
279      * <p>
280      * The constructor uses the time zone of the chronology specified.
281      * Once the constructor is complete, all further calculations are performed
282      * without reference to a timezone (by switching to UTC).
283      *
284      * @param year the year
285      * @param monthOfYear the month of the year
286      * @param dayOfMonth the day of the month
287      * @param chronology the chronology, null means ISOChronology in the default zone
288      */

289     public YearMonthDay(int year, int monthOfYear, int dayOfMonth, Chronology chronology) {
290         super(new int[] {year, monthOfYear, dayOfMonth}, chronology);
291     }
292
293     /**
294      * Constructs a YearMonthDay with chronology from this instance and new values.
295      *
296      * @param partial the partial to base this new instance on
297      * @param values the new set of values
298      */

299     YearMonthDay(YearMonthDay partial, int[] values) {
300         super(partial, values);
301     }
302
303     /**
304      * Constructs a YearMonthDay with values from this instance and a new chronology.
305      *
306      * @param partial the partial to base this new instance on
307      * @param chrono the new chronology
308      */

309     YearMonthDay(YearMonthDay partial, Chronology chrono) {
310         super(partial, chrono);
311     }
312
313     //-----------------------------------------------------------------------
314
/**
315      * Gets the number of fields in this partial.
316      *
317      * @return the field count
318      */

319     public int size() {
320         return 3;
321     }
322
323     /**
324      * Gets the field for a specific index in the chronology specified.
325      * <p>
326      * This method must not use any instance variables.
327      *
328      * @param index the index to retrieve
329      * @param chrono the chronology to use
330      * @return the field
331      */

332     protected DateTimeField getField(int index, Chronology chrono) {
333         switch (index) {
334             case YEAR:
335                 return chrono.year();
336             case MONTH_OF_YEAR:
337                 return chrono.monthOfYear();
338             case DAY_OF_MONTH:
339                 return chrono.dayOfMonth();
340             default:
341                 throw new IndexOutOfBoundsException JavaDoc("Invalid index: " + index);
342         }
343     }
344
345     /**
346      * Gets the field type at the specified index.
347      *
348      * @param index the index to retrieve
349      * @return the field at the specified index
350      * @throws IndexOutOfBoundsException if the index is invalid
351      */

352     public DateTimeFieldType getFieldType(int index) {
353         return FIELD_TYPES[index];
354     }
355
356     /**
357      * Gets an array of the field type of each of the fields that this partial supports.
358      * <p>
359      * The fields are returned largest to smallest, Year, Month, Day
360      *
361      * @return the array of field types (cloned), largest to smallest
362      */

363     public DateTimeFieldType[] getFieldTypes() {
364         return (DateTimeFieldType[]) FIELD_TYPES.clone();
365     }
366
367     //-----------------------------------------------------------------------
368
/**
369      * Returns a copy of this date with the specified chronology.
370      * This instance is immutable and unaffected by this method call.
371      * <p>
372      * This method retains the values of the fields, thus the result will
373      * typically refer to a different instant.
374      * <p>
375      * The time zone of the specified chronology is ignored, as YearMonthDay
376      * operates without a time zone.
377      *
378      * @param newChronology the new chronology, null means ISO
379      * @return a copy of this datetime with a different chronology
380      * @throws IllegalArgumentException if the values are invalid for the new chronology
381      */

382     public YearMonthDay withChronologyRetainFields(Chronology newChronology) {
383         newChronology = DateTimeUtils.getChronology(newChronology);
384         newChronology = newChronology.withUTC();
385         if (newChronology == getChronology()) {
386             return this;
387         } else {
388             YearMonthDay newYearMonthDay = new YearMonthDay(this, newChronology);
389             newChronology.validate(newYearMonthDay, getValues());
390             return newYearMonthDay;
391         }
392     }
393
394     /**
395      * Returns a copy of this date with the specified field set to a new value.
396      * <p>
397      * For example, if the field type is <code>dayOfMonth</code> then the day
398      * would be changed in the returned instance.
399      * <p>
400      * These three lines are equivalent:
401      * <pre>
402      * YearMonthDay updated = ymd.withField(DateTimeFieldType.dayOfMonth(), 6);
403      * YearMonthDay updated = ymd.dayOfMonth().setCopy(6);
404      * YearMonthDay updated = ymd.property(DateTimeFieldType.dayOfMonth()).setCopy(6);
405      * </pre>
406      *
407      * @param fieldType the field type to set, not null
408      * @param value the value to set
409      * @return a copy of this instance with the field set
410      * @throws IllegalArgumentException if the value is null or invalid
411      */

412     public YearMonthDay withField(DateTimeFieldType fieldType, int value) {
413         int index = indexOfSupported(fieldType);
414         if (value == getValue(index)) {
415             return this;
416         }
417         int[] newValues = getValues();
418         newValues = getField(index).set(this, index, newValues, value);
419         return new YearMonthDay(this, newValues);
420     }
421
422     /**
423      * Returns a copy of this date with the value of the specified field increased.
424      * <p>
425      * If the addition is zero, then <code>this</code> is returned.
426      * <p>
427      * These three lines are equivalent:
428      * <pre>
429      * YearMonthDay added = ymd.withFieldAdded(DurationFieldType.days(), 6);
430      * YearMonthDay added = ymd.plusDays(6);
431      * YearMonthDay added = ymd.dayOfMonth().addToCopy(6);
432      * </pre>
433      *
434      * @param fieldType the field type to add to, not null
435      * @param amount the amount to add
436      * @return a copy of this instance with the field updated
437      * @throws IllegalArgumentException if the value is null or invalid
438      * @throws ArithmeticException if the new datetime exceeds the capacity
439      */

440     public YearMonthDay withFieldAdded(DurationFieldType fieldType, int amount) {
441         int index = indexOfSupported(fieldType);
442         if (amount == 0) {
443             return this;
444         }
445         int[] newValues = getValues();
446         newValues = getField(index).add(this, index, newValues, amount);
447         return new YearMonthDay(this, newValues);
448     }
449
450     /**
451      * Returns a copy of this date with the specified period added.
452      * <p>
453      * If the addition is zero, then <code>this</code> is returned.
454      * Fields in the period that aren't present in the partial are ignored.
455      * <p>
456      * This method is typically used to add multiple copies of complex
457      * period instances. Adding one field is best achieved using methods
458      * like {@link #withFieldAdded(DurationFieldType, int)}
459      * or {@link #plusYears(int)}.
460      *
461      * @param period the period to add to this one, null means zero
462      * @param scalar the amount of times to add, such as -1 to subtract once
463      * @return a copy of this instance with the period added
464      * @throws ArithmeticException if the new datetime exceeds the capacity
465      */

466     public YearMonthDay withPeriodAdded(ReadablePeriod period, int scalar) {
467         if (period == null || scalar == 0) {
468             return this;
469         }
470         int[] newValues = getValues();
471         for (int i = 0; i < period.size(); i++) {
472             DurationFieldType fieldType = period.getFieldType(i);
473             int index = indexOf(fieldType);
474             if (index >= 0) {
475                 newValues = getField(index).add(this, index, newValues,
476                         FieldUtils.safeMultiply(period.getValue(i), scalar));
477             }
478         }
479         return new YearMonthDay(this, newValues);
480     }
481
482     //-----------------------------------------------------------------------
483
/**
484      * Returns a copy of this date with the specified period added.
485      * <p>
486      * If the amount is zero or null, then <code>this</code> is returned.
487      * <p>
488      * This method is typically used to add complex period instances.
489      * Adding one field is best achieved using methods
490      * like {@link #plusYears(int)}.
491      *
492      * @param period the duration to add to this one, null means zero
493      * @return a copy of this instance with the period added
494      * @throws ArithmeticException if the new datetime exceeds the capacity of a long
495      */

496     public YearMonthDay plus(ReadablePeriod period) {
497         return withPeriodAdded(period, 1);
498     }
499
500     //-----------------------------------------------------------------------
501
/**
502      * Returns a copy of this date plus the specified number of years.
503      * <p>
504      * This date instance is immutable and unaffected by this method call.
505      * <p>
506      * The following three lines are identical in effect:
507      * <pre>
508      * YearMonthDay added = dt.plusYears(6);
509      * YearMonthDay added = dt.plus(Period.years(6));
510      * YearMonthDay added = dt.withFieldAdded(DurationFieldType.years(), 6);
511      * </pre>
512      *
513      * @param years the amount of years to add, may be negative
514      * @return the new date plus the increased years
515      * @since 1.1
516      */

517     public YearMonthDay plusYears(int years) {
518         return withFieldAdded(DurationFieldType.years(), years);
519     }
520
521     /**
522      * Returns a copy of this date plus the specified number of months.
523      * <p>
524      * This date instance is immutable and unaffected by this method call.
525      * <p>
526      * The following three lines are identical in effect:
527      * <pre>
528      * YearMonthDay added = dt.plusMonths(6);
529      * YearMonthDay added = dt.plus(Period.months(6));
530      * YearMonthDay added = dt.withFieldAdded(DurationFieldType.months(), 6);
531      * </pre>
532      *
533      * @param months the amount of months to add, may be negative
534      * @return the new date plus the increased months
535      * @since 1.1
536      */

537     public YearMonthDay plusMonths(int months) {
538         return withFieldAdded(DurationFieldType.months(), months);
539     }
540
541     /**
542      * Returns a copy of this date plus the specified number of days.
543      * <p>
544      * This date instance is immutable and unaffected by this method call.
545      * <p>
546      * The following three lines are identical in effect:
547      * <pre>
548      * YearMonthDay added = dt.plusDays(6);
549      * YearMonthDay added = dt.plus(Period.days(6));
550      * YearMonthDay added = dt.withFieldAdded(DurationFieldType.days(), 6);
551      * </pre>
552      *
553      * @param days the amount of days to add, may be negative
554      * @return the new date plus the increased days
555      * @since 1.1
556      */

557     public YearMonthDay plusDays(int days) {
558         return withFieldAdded(DurationFieldType.days(), days);
559     }
560
561     //-----------------------------------------------------------------------
562
/**
563      * Returns a copy of this date with the specified period taken away.
564      * <p>
565      * If the amount is zero or null, then <code>this</code> is returned.
566      * <p>
567      * This method is typically used to subtract complex period instances.
568      * Subtracting one field is best achieved using methods
569      * like {@link #minusYears(int)}.
570      *
571      * @param period the period to reduce this instant by
572      * @return a copy of this instance with the period taken away
573      * @throws ArithmeticException if the new datetime exceeds the capacity of a long
574      */

575     public YearMonthDay minus(ReadablePeriod period) {
576         return withPeriodAdded(period, -1);
577     }
578
579     //-----------------------------------------------------------------------
580
/**
581      * Returns a copy of this date minus the specified number of years.
582      * <p>
583      * This datetime instance is immutable and unaffected by this method call.
584      * <p>
585      * The following three lines are identical in effect:
586      * <pre>
587      * YearMonthDay subtracted = dt.minusYears(6);
588      * YearMonthDay subtracted = dt.minus(Period.years(6));
589      * YearMonthDay subtracted = dt.withFieldAdded(DurationFieldType.years(), -6);
590      * </pre>
591      *
592      * @param years the amount of years to subtract, may be negative
593      * @return the new datetime minus the increased years
594      * @since 1.1
595      */

596     public YearMonthDay minusYears(int years) {
597         return withFieldAdded(DurationFieldType.years(), FieldUtils.safeNegate(years));
598     }
599
600     /**
601      * Returns a copy of this date minus the specified number of months.
602      * <p>
603      * This datetime instance is immutable and unaffected by this method call.
604      * <p>
605      * The following three lines are identical in effect:
606      * <pre>
607      * YearMonthDay subtracted = dt.minusMonths(6);
608      * YearMonthDay subtracted = dt.minus(Period.months(6));
609      * YearMonthDay subtracted = dt.withFieldAdded(DurationFieldType.months(), -6);
610      * </pre>
611      *
612      * @param months the amount of months to subtract, may be negative
613      * @return the new datetime minus the increased months
614      * @since 1.1
615      */

616     public YearMonthDay minusMonths(int months) {
617         return withFieldAdded(DurationFieldType.months(), FieldUtils.safeNegate(months));
618     }
619
620     /**
621      * Returns a copy of this date minus the specified number of days.
622      * <p>
623      * This datetime instance is immutable and unaffected by this method call.
624      * <p>
625      * The following three lines are identical in effect:
626      * <pre>
627      * YearMonthDay subtracted = dt.minusDays(6);
628      * YearMonthDay subtracted = dt.minus(Period.days(6));
629      * YearMonthDay subtracted = dt.withFieldAdded(DurationFieldType.days(), -6);
630      * </pre>
631      *
632      * @param days the amount of days to subtract, may be negative
633      * @return the new datetime minus the increased days
634      * @since 1.1
635      */

636     public YearMonthDay minusDays(int days) {
637         return withFieldAdded(DurationFieldType.days(), FieldUtils.safeNegate(days));
638     }
639
640     //-----------------------------------------------------------------------
641
/**
642      * Gets the property object for the specified type, which contains
643      * many useful methods.
644      *
645      * @param type the field type to get the property for
646      * @return the property object
647      * @throws IllegalArgumentException if the field is null or unsupported
648      */

649     public Property property(DateTimeFieldType type) {
650         return new Property(this, indexOfSupported(type));
651     }
652
653     //-----------------------------------------------------------------------
654
/**
655      * Converts this object to a LocalDate with the same date and chronology.
656      *
657      * @return a LocalDate with the same date and chronology
658      * @since 1.3
659      */

660     public LocalDate toLocalDate() {
661         return new LocalDate(getYear(), getMonthOfYear(), getDayOfMonth(), getChronology());
662     }
663
664     //-----------------------------------------------------------------------
665
/**
666      * Converts this YearMonthDay to a full datetime at midnight using the
667      * default time zone.
668      *
669      * @return this date as a datetime at midnight
670      */

671     public DateTime toDateTimeAtMidnight() {
672         return toDateTimeAtMidnight(null);
673     }
674
675     /**
676      * Converts this YearMonthDay to a full datetime at midnight using the
677      * specified time zone.
678      * <p>
679      * This method uses the chronology from this instance plus the time zone
680      * specified.
681      *
682      * @param zone the zone to use, null means default
683      * @return this date as a datetime at midnight
684      */

685     public DateTime toDateTimeAtMidnight(DateTimeZone zone) {
686         Chronology chrono = getChronology().withZone(zone);
687         return new DateTime(getYear(), getMonthOfYear(), getDayOfMonth(), 0, 0, 0, 0, chrono);
688     }
689
690     //-----------------------------------------------------------------------
691
/**
692      * Converts this partial to a full datetime using the default time zone
693      * setting the date fields from this instance and the time fields from
694      * the current time.
695      *
696      * @return this date as a datetime with the time as the current time
697      */

698     public DateTime toDateTimeAtCurrentTime() {
699         return toDateTimeAtCurrentTime(null);
700     }
701
702     /**
703      * Converts this partial to a full datetime using the specified time zone
704      * setting the date fields from this instance and the time fields from
705      * the current time.
706      * <p>
707      * This method uses the chronology from this instance plus the time zone
708      * specified.
709      *
710      * @param zone the zone to use, null means default
711      * @return this date as a datetime with the time as the current time
712      */

713     public DateTime toDateTimeAtCurrentTime(DateTimeZone zone) {
714         Chronology chrono = getChronology().withZone(zone);
715         long instantMillis = DateTimeUtils.currentTimeMillis();
716         long resolved = chrono.set(this, instantMillis);
717         return new DateTime(resolved, chrono);
718     }
719
720     //-----------------------------------------------------------------------
721
/**
722      * Converts this object to a DateMidnight in the default time zone.
723      *
724      * @return the DateMidnight instance in the default zone
725      */

726     public DateMidnight toDateMidnight() {
727         return toDateMidnight(null);
728     }
729
730     /**
731      * Converts this object to a DateMidnight.
732      *
733      * @param zone the zone to get the DateMidnight in, null means default
734      * @return the DateMidnight instance
735      */

736     public DateMidnight toDateMidnight(DateTimeZone zone) {
737         Chronology chrono = getChronology().withZone(zone);
738         return new DateMidnight(getYear(), getMonthOfYear(), getDayOfMonth(), chrono);
739     }
740
741     //-----------------------------------------------------------------------
742
/**
743      * Converts this object to a DateTime using a TimeOfDay to fill in the
744      * missing fields and using the default time zone.
745      * This instance is immutable and unaffected by this method call.
746      * <p>
747      * The resulting chronology is determined by the chronology of this
748      * YearMonthDay plus the time zone.
749      * The chronology of the time is ignored - only the field values are used.
750      *
751      * @param time the time of day to use, null means current time
752      * @return the DateTime instance
753      */

754     public DateTime toDateTime(TimeOfDay time) {
755         return toDateTime(time, null);
756     }
757
758     /**
759      * Converts this object to a DateTime using a TimeOfDay to fill in the
760      * missing fields.
761      * This instance is immutable and unaffected by this method call.
762      * <p>
763      * The resulting chronology is determined by the chronology of this
764      * YearMonthDay plus the time zone.
765      * The chronology of the time is ignored - only the field values are used.
766      *
767      * @param time the time of day to use, null means current time
768      * @param zone the zone to get the DateTime in, null means default
769      * @return the DateTime instance
770      */

771     public DateTime toDateTime(TimeOfDay time, DateTimeZone zone) {
772         Chronology chrono = getChronology().withZone(zone);
773         long instant = DateTimeUtils.currentTimeMillis();
774         instant = chrono.set(this, instant);
775         if (time != null) {
776             instant = chrono.set(time, instant);
777         }
778         return new DateTime(instant, chrono);
779     }
780
781     //-----------------------------------------------------------------------
782
/**
783      * Converts this object to an Interval representing the whole day
784      * in the default time zone.
785      *
786      * @return a interval over the day
787      */

788     public Interval toInterval() {
789         return toInterval(null);
790     }
791
792     /**
793      * Converts this object to an Interval representing the whole day.
794      *
795      * @param zone the zone to get the Interval in, null means default
796      * @return a interval over the day
797      */

798     public Interval toInterval(DateTimeZone zone) {
799         zone = DateTimeUtils.getZone(zone);
800         return toDateMidnight(zone).toInterval();
801     }
802
803     //-----------------------------------------------------------------------
804
/**
805      * Get the year field value.
806      *
807      * @return the year
808      */

809     public int getYear() {
810         return getValue(YEAR);
811     }
812
813     /**
814      * Get the month of year field value.
815      *
816      * @return the month of year
817      */

818     public int getMonthOfYear() {
819         return getValue(MONTH_OF_YEAR);
820     }
821
822     /**
823      * Get the day of month field value.
824      *
825      * @return the day of month
826      */

827     public int getDayOfMonth() {
828         return getValue(DAY_OF_MONTH);
829     }
830
831     //-----------------------------------------------------------------------
832
/**
833      * Returns a copy of this date with the year field updated.
834      * <p>
835      * YearMonthDay is immutable, so there are no set methods.
836      * Instead, this method returns a new instance with the value of
837      * year changed.
838      *
839      * @param year the year to set
840      * @return a copy of this object with the field set
841      * @throws IllegalArgumentException if the value is invalid
842      * @since 1.3
843      */

844     public YearMonthDay withYear(int year) {
845         int[] newValues = getValues();
846         newValues = getChronology().year().set(this, YEAR, newValues, year);
847         return new YearMonthDay(this, newValues);
848     }
849
850     /**
851      * Returns a copy of this date with the month of year field updated.
852      * <p>
853      * YearMonthDay is immutable, so there are no set methods.
854      * Instead, this method returns a new instance with the value of
855      * month of year changed.
856      *
857      * @param monthOfYear the month of year to set
858      * @return a copy of this object with the field set
859      * @throws IllegalArgumentException if the value is invalid
860      * @since 1.3
861      */

862     public YearMonthDay withMonthOfYear(int monthOfYear) {
863         int[] newValues = getValues();
864         newValues = getChronology().monthOfYear().set(this, MONTH_OF_YEAR, newValues, monthOfYear);
865         return new YearMonthDay(this, newValues);
866     }
867
868     /**
869      * Returns a copy of this date with the day of month field updated.
870      * <p>
871      * YearMonthDay is immutable, so there are no set methods.
872      * Instead, this method returns a new instance with the value of
873      * day of month changed.
874      *
875      * @param dayOfMonth the day of month to set
876      * @return a copy of this object with the field set
877      * @throws IllegalArgumentException if the value is invalid
878      * @since 1.3
879      */

880     public YearMonthDay withDayOfMonth(int dayOfMonth) {
881         int[] newValues = getValues();
882         newValues = getChronology().dayOfMonth().set(this, DAY_OF_MONTH, newValues, dayOfMonth);
883         return new YearMonthDay(this, newValues);
884     }
885
886     //-----------------------------------------------------------------------
887
/**
888      * Get the year field property which provides access to advanced functionality.
889      *
890      * @return the year property
891      */

892     public Property year() {
893         return new Property(this, YEAR);
894     }
895
896     /**
897      * Get the month of year field property which provides access to advanced functionality.
898      *
899      * @return the month of year property
900      */

901     public Property monthOfYear() {
902         return new Property(this, MONTH_OF_YEAR);
903     }
904
905     /**
906      * Get the day of month field property which provides access to advanced functionality.
907      *
908      * @return the day of month property
909      */

910     public Property dayOfMonth() {
911         return new Property(this, DAY_OF_MONTH);
912     }
913
914     //-----------------------------------------------------------------------
915
/**
916      * Output the date in the ISO8601 format YYYY-MM-DD.
917      *
918      * @return ISO8601 formatted string
919      */

920     public String JavaDoc toString() {
921         return ISODateTimeFormat.yearMonthDay().print(this);
922     }
923
924     //-----------------------------------------------------------------------
925
/**
926      * The property class for <code>YearMonthDay</code>.
927      * <p>
928      * This class binds a <code>YearMonthDay</code> to a <code>DateTimeField</code>.
929      *
930      * @author Stephen Colebourne
931      * @since 1.0
932      */

933     public static class Property extends AbstractPartialFieldProperty implements Serializable JavaDoc {
934
935         /** Serialization version */
936         private static final long serialVersionUID = 5727734012190224363L;
937
938         /** The partial */
939         private final YearMonthDay iYearMonthDay;
940         /** The field index */
941         private final int iFieldIndex;
942
943         /**
944          * Constructs a property.
945          *
946          * @param partial the partial instance
947          * @param fieldIndex the index in the partial
948          */

949         Property(YearMonthDay partial, int fieldIndex) {
950             super();
951             iYearMonthDay = partial;
952             iFieldIndex = fieldIndex;
953         }
954
955         /**
956          * Gets the field that this property uses.
957          *
958          * @return the field
959          */

960         public DateTimeField getField() {
961             return iYearMonthDay.getField(iFieldIndex);
962         }
963
964         /**
965          * Gets the partial that this property belongs to.
966          *
967          * @return the partial
968          */

969         protected ReadablePartial getReadablePartial() {
970             return iYearMonthDay;
971         }
972
973         /**
974          * Gets the partial that this property belongs to.
975          *
976          * @return the partial
977          */

978         public YearMonthDay getYearMonthDay() {
979             return iYearMonthDay;
980         }
981
982         /**
983          * Gets the value of this field.
984          *
985          * @return the field value
986          */

987         public int get() {
988             return iYearMonthDay.getValue(iFieldIndex);
989         }
990
991         //-----------------------------------------------------------------------
992
/**
993          * Adds to the value of this field in a copy of this YearMonthDay.
994          * <p>
995          * The value will be added to this field. If the value is too large to be
996          * added solely to this field then it will affect larger fields.
997          * Smaller fields are unaffected.
998          * <p>
999          * If the result would be too large, beyond the maximum year, then an
1000         * IllegalArgumentException is thrown.
1001         * <p>
1002         * The YearMonthDay attached to this property is unchanged by this call.
1003         * Instead, a new instance is returned.
1004         *
1005         * @param valueToAdd the value to add to the field in the copy
1006         * @return a copy of the YearMonthDay with the field value changed
1007         * @throws IllegalArgumentException if the value isn't valid
1008         */

1009        public YearMonthDay addToCopy(int valueToAdd) {
1010            int[] newValues = iYearMonthDay.getValues();
1011            newValues = getField().add(iYearMonthDay, iFieldIndex, newValues, valueToAdd);
1012            return new YearMonthDay(iYearMonthDay, newValues);
1013        }
1014
1015        /**
1016         * Adds to the value of this field in a copy of this YearMonthDay wrapping
1017         * within this field if the maximum value is reached.
1018         * <p>
1019         * The value will be added to this field. If the value is too large to be
1020         * added solely to this field then it wraps within this field.
1021         * Other fields are unaffected.
1022         * <p>
1023         * For example,
1024         * <code>2004-12-20</code> addWrapField one month returns <code>2004-01-20</code>.
1025         * <p>
1026         * The YearMonthDay attached to this property is unchanged by this call.
1027         * Instead, a new instance is returned.
1028         *
1029         * @param valueToAdd the value to add to the field in the copy
1030         * @return a copy of the YearMonthDay with the field value changed
1031         * @throws IllegalArgumentException if the value isn't valid
1032         */

1033        public YearMonthDay addWrapFieldToCopy(int valueToAdd) {
1034            int[] newValues = iYearMonthDay.getValues();
1035            newValues = getField().addWrapField(iYearMonthDay, iFieldIndex, newValues, valueToAdd);
1036            return new YearMonthDay(iYearMonthDay, newValues);
1037        }
1038
1039        //-----------------------------------------------------------------------
1040
/**
1041         * Sets this field in a copy of the YearMonthDay.
1042         * <p>
1043         * The YearMonthDay attached to this property is unchanged by this call.
1044         * Instead, a new instance is returned.
1045         *
1046         * @param value the value to set the field in the copy to
1047         * @return a copy of the YearMonthDay with the field value changed
1048         * @throws IllegalArgumentException if the value isn't valid
1049         */

1050        public YearMonthDay setCopy(int value) {
1051            int[] newValues = iYearMonthDay.getValues();
1052            newValues = getField().set(iYearMonthDay, iFieldIndex, newValues, value);
1053            return new YearMonthDay(iYearMonthDay, newValues);
1054        }
1055
1056        /**
1057         * Sets this field in a copy of the YearMonthDay to a parsed text value.
1058         * <p>
1059         * The YearMonthDay attached to this property is unchanged by this call.
1060         * Instead, a new instance is returned.
1061         *
1062         * @param text the text value to set
1063         * @param locale optional locale to use for selecting a text symbol
1064         * @return a copy of the YearMonthDay with the field value changed
1065         * @throws IllegalArgumentException if the text value isn't valid
1066         */

1067        public YearMonthDay setCopy(String JavaDoc text, Locale JavaDoc locale) {
1068            int[] newValues = iYearMonthDay.getValues();
1069            newValues = getField().set(iYearMonthDay, iFieldIndex, newValues, text, locale);
1070            return new YearMonthDay(iYearMonthDay, newValues);
1071        }
1072
1073        /**
1074         * Sets this field in a copy of the YearMonthDay to a parsed text value.
1075         * <p>
1076         * The YearMonthDay attached to this property is unchanged by this call.
1077         * Instead, a new instance is returned.
1078         *
1079         * @param text the text value to set
1080         * @return a copy of the YearMonthDay with the field value changed
1081         * @throws IllegalArgumentException if the text value isn't valid
1082         */

1083        public YearMonthDay setCopy(String JavaDoc text) {
1084            return setCopy(text, null);
1085        }
1086
1087        //-----------------------------------------------------------------------
1088
/**
1089         * Returns a new YearMonthDay with this field set to the maximum value
1090         * for this field.
1091         * <p>
1092         * This operation is useful for obtaining a DateTime on the last day
1093         * of the month, as month lengths vary.
1094         * <pre>
1095         * YearMonthDay lastDayOfMonth = dt.dayOfMonth().withMaximumValue();
1096         * </pre>
1097         * <p>
1098         * The YearMonthDay attached to this property is unchanged by this call.
1099         *
1100         * @return a copy of the YearMonthDay with this field set to its maximum
1101         * @since 1.2
1102         */

1103        public YearMonthDay withMaximumValue() {
1104            return setCopy(getMaximumValue());
1105        }
1106
1107        /**
1108         * Returns a new YearMonthDay with this field set to the minimum value
1109         * for this field.
1110         * <p>
1111         * The YearMonthDay attached to this property is unchanged by this call.
1112         *
1113         * @return a copy of the YearMonthDay with this field set to its minimum
1114         * @since 1.2
1115         */

1116        public YearMonthDay withMinimumValue() {
1117            return setCopy(getMinimumValue());
1118        }
1119    }
1120
1121}
1122
Popular Tags