KickJava   Java API By Example, From Geeks To Geeks.

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


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
20 import org.joda.time.base.BasePeriod;
21
22 /**
23  * An immutable time period specifying a set of duration field values.
24  * <p>
25  * A time period is divided into a number of fields, such as hours and seconds.
26  * Which fields are supported is defined by the PeriodType class.
27  * The default is the standard period type, which supports years, months, weeks, days,
28  * hours, minutes, seconds and millis.
29  * <p>
30  * When this time period is added to an instant, the effect is of adding each field in turn.
31  * As a result, this takes into account daylight savings time.
32  * Adding a time period of 1 day to the day before daylight savings starts will only add
33  * 23 hours rather than 24 to ensure that the time remains the same.
34  * If this is not the behaviour you want, then see {@link Duration}.
35  * <p>
36  * The definition of a period also affects the equals method. A period of 1
37  * day is not equal to a period of 24 hours, nor 1 hour equal to 60 minutes.
38  * This is because periods represent an abstracted definition of a time period
39  * (eg. a day may not actually be 24 hours, it might be 23 or 25 at daylight
40  * savings boundary). To compare the actual duration of two periods, convert
41  * both to durations using toDuration, an operation that emphasises that the
42  * result may differ according to the date you choose.
43  * <p>
44  * Period is thread-safe and immutable, provided that the PeriodType is as well.
45  * All standard PeriodType classes supplied are thread-safe and immutable.
46  *
47  * @author Brian S O'Neill
48  * @author Stephen Colebourne
49  * @since 1.0
50  * @see MutablePeriod
51  */

52 public final class Period
53         extends BasePeriod
54         implements ReadablePeriod, Serializable JavaDoc {
55
56     /**
57      * A period of zero length and standard period type.
58      * @since 1.4
59      */

60     public static final Period ZERO = new Period();
61
62     /** Serialization version */
63     private static final long serialVersionUID = 741052353876488155L;
64
65     //-----------------------------------------------------------------------
66
/**
67      * Create a period with a specified number of years.
68      * <p>
69      * The standard period type is used, thus you can add other fields such
70      * as months or days using the <code>withXxx()</code> methods.
71      * For example, <code>Period.years(2).withMonths(6);</code>
72      * <p>
73      * If you want a year-based period that cannot have other fields added,
74      * then you should consider using {@link Years}.
75      *
76      * @param years the amount of years in this period
77      * @return the period
78      */

79     public static Period years(int years) {
80         return new Period(new int[] {years, 0, 0, 0, 0, 0, 0, 0, 0}, PeriodType.standard());
81     }
82
83     /**
84      * Create a period with a specified number of months.
85      * <p>
86      * The standard period type is used, thus you can add other fields such
87      * as years or days using the <code>withXxx()</code> methods.
88      * For example, <code>Period.months(2).withDays(6);</code>
89      * <p>
90      * If you want a month-based period that cannot have other fields added,
91      * then you should consider using {@link Months}.
92      *
93      * @param months the amount of months in this period
94      * @return the period
95      */

96     public static Period months(int months) {
97         return new Period(new int[] {0, months, 0, 0, 0, 0, 0, 0}, PeriodType.standard());
98     }
99
100     /**
101      * Create a period with a specified number of weeks.
102      * <p>
103      * The standard period type is used, thus you can add other fields such
104      * as months or days using the <code>withXxx()</code> methods.
105      * For example, <code>Period.weeks(2).withDays(6);</code>
106      * <p>
107      * If you want a week-based period that cannot have other fields added,
108      * then you should consider using {@link Weeks}.
109      *
110      * @param weeks the amount of weeks in this period
111      * @return the period
112      */

113     public static Period weeks(int weeks) {
114         return new Period(new int[] {0, 0, weeks, 0, 0, 0, 0, 0}, PeriodType.standard());
115     }
116
117     /**
118      * Create a period with a specified number of days.
119      * <p>
120      * The standard period type is used, thus you can add other fields such
121      * as months or weeks using the <code>withXxx()</code> methods.
122      * For example, <code>Period.days(2).withHours(6);</code>
123      * <p>
124      * If you want a day-based period that cannot have other fields added,
125      * then you should consider using {@link Days}.
126      *
127      * @param days the amount of days in this period
128      * @return the period
129      */

130     public static Period days(int days) {
131         return new Period(new int[] {0, 0, 0, days, 0, 0, 0, 0}, PeriodType.standard());
132     }
133
134     /**
135      * Create a period with a specified number of hours.
136      * <p>
137      * The standard period type is used, thus you can add other fields such
138      * as months or days using the <code>withXxx()</code> methods.
139      * For example, <code>Period.hours(2).withMinutes(30);</code>
140      * <p>
141      * If you want a hour-based period that cannot have other fields added,
142      * then you should consider using {@link Hours}.
143      *
144      * @param hours the amount of hours in this period
145      * @return the period
146      */

147     public static Period hours(int hours) {
148         return new Period(new int[] {0, 0, 0, 0, hours, 0, 0, 0}, PeriodType.standard());
149     }
150
151     /**
152      * Create a period with a specified number of minutes.
153      * <p>
154      * The standard period type is used, thus you can add other fields such
155      * as days or hours using the <code>withXxx()</code> methods.
156      * For example, <code>Period.minutes(2).withSeconds(30);</code>
157      * <p>
158      * If you want a minute-based period that cannot have other fields added,
159      * then you should consider using {@link Minutes}.
160      *
161      * @param minutes the amount of minutes in this period
162      * @return the period
163      */

164     public static Period minutes(int minutes) {
165         return new Period(new int[] {0, 0, 0, 0, 0, minutes, 0, 0}, PeriodType.standard());
166     }
167
168     /**
169      * Create a period with a specified number of seconds.
170      * <p>
171      * The standard period type is used, thus you can add other fields such
172      * as days or hours using the <code>withXxx()</code> methods.
173      * For example, <code>Period.seconds(2).withMillis(30);</code>
174      * <p>
175      * If you want a second-based period that cannot have other fields added,
176      * then you should consider using {@link Seconds}.
177      *
178      * @param seconds the amount of seconds in this period
179      * @return the period
180      */

181     public static Period seconds(int seconds) {
182         return new Period(new int[] {0, 0, 0, 0, 0, 0, seconds, 0}, PeriodType.standard());
183     }
184
185     /**
186      * Create a period with a specified number of millis.
187      * <p>
188      * The standard period type is used, thus you can add other fields such
189      * as days or hours using the <code>withXxx()</code> methods.
190      * For example, <code>Period.millis(20).withSeconds(30);</code>
191      *
192      * @param millis the amount of millis in this period
193      * @return the period
194      */

195     public static Period millis(int millis) {
196         return new Period(new int[] {0, 0, 0, 0, 0, 0, 0, millis}, PeriodType.standard());
197     }
198
199     //-----------------------------------------------------------------------
200
/**
201      * Creates a period from two partially specified times, calculating
202      * by field difference.
203      * <p>
204      * The two partials must contain the same fields, thus you can specify
205      * two <code>LocalDate</code> objects, or two <code>LocalTime</code> objects,
206      * but not one of each. Also, the partial may not contain overlapping
207      * fields, such as dayOfWeek and dayOfMonth.
208      * <p>
209      * Calculation by field difference works by extracting the difference
210      * one field at a time and not wrapping into other fields.
211      * Thus 2005-06-09/2007-04-12 will yield P1Y-2M3D.
212      * <p>
213      * For example, you have an event that always runs from the 27th of
214      * each month to the 2nd of the next month. If you calculate this
215      * period using a standard constructor, then you will get between
216      * P3D and P6D depending on the month. If you use this method, then
217      * you will get P1M-25D. This field-difference based period can
218      * be successfully applied to each month of the year to obtain the
219      * correct end date for a given start date.
220      *
221      * @param start the start of the period, must not be null
222      * @param end the end of the period, must not be null
223      * @throws IllegalArgumentException if the partials are null or invalid
224      * @since 1.1
225      */

226     public static Period fieldDifference(ReadablePartial start, ReadablePartial end) {
227         if (start == null || end == null) {
228             throw new IllegalArgumentException JavaDoc("ReadablePartial objects must not be null");
229         }
230         if (start.size() != end.size()) {
231             throw new IllegalArgumentException JavaDoc("ReadablePartial objects must have the same set of fields");
232         }
233         DurationFieldType[] types = new DurationFieldType[start.size()];
234         int[] values = new int[start.size()];
235         for (int i = 0, isize = start.size(); i < isize; i++) {
236             if (start.getFieldType(i) != end.getFieldType(i)) {
237                 throw new IllegalArgumentException JavaDoc("ReadablePartial objects must have the same set of fields");
238             }
239             types[i] = start.getFieldType(i).getDurationType();
240             if (i > 0 && types[i - 1] == types[i]) {
241                 throw new IllegalArgumentException JavaDoc("ReadablePartial objects must not have overlapping fields");
242             }
243             values[i] = end.getValue(i) - start.getValue(i);
244         }
245         return new Period(values, PeriodType.forFields(types));
246     }
247
248     //-----------------------------------------------------------------------
249
/**
250      * Creates a new empty period with the standard set of fields.
251      * <p>
252      * One way to initialise a period is as follows:
253      * <pre>
254      * Period = new Period().withYears(6).withMonths(3).withSeconds(23);
255      * </pre>
256      * Bear in mind that this creates four period instances in total, three of
257      * which are immediately discarded.
258      * The alterative is more efficient, but less readable:
259      * <pre>
260      * Period = new Period(6, 3, 0, 0, 0, 0, 23, 0);
261      * </pre>
262      * The following is also slightly less wasteful:
263      * <pre>
264      * Period = Period.years(6).withMonths(3).withSeconds(23);
265      * </pre>
266      */

267     public Period() {
268         super(0L, null, null);
269     }
270
271     /**
272      * Create a period from a set of field values using the standard set of fields.
273      * Note that the parameters specify the time fields hours, minutes,
274      * seconds and millis, not the date fields.
275      *
276      * @param hours amount of hours in this period
277      * @param minutes amount of minutes in this period
278      * @param seconds amount of seconds in this period
279      * @param millis amount of milliseconds in this period
280      */

281     public Period(int hours, int minutes, int seconds, int millis) {
282         super(0, 0, 0, 0, hours, minutes, seconds, millis, PeriodType.standard());
283     }
284
285     /**
286      * Create a period from a set of field values using the standard set of fields.
287      *
288      * @param years amount of years in this period
289      * @param months amount of months in this period
290      * @param weeks amount of weeks in this period
291      * @param days amount of days in this period
292      * @param hours amount of hours in this period
293      * @param minutes amount of minutes in this period
294      * @param seconds amount of seconds in this period
295      * @param millis amount of milliseconds in this period
296      */

297     public Period(int years, int months, int weeks, int days,
298                   int hours, int minutes, int seconds, int millis) {
299         super(years, months, weeks, days, hours, minutes, seconds, millis, PeriodType.standard());
300     }
301
302     /**
303      * Create a period from a set of field values.
304      * <p>
305      * There is usually little need to use this constructor.
306      * The period type is used primarily to define how to split an interval into a period.
307      * As this constructor already is split, the period type does no real work.
308      *
309      * @param years amount of years in this period, which must be zero if unsupported
310      * @param months amount of months in this period, which must be zero if unsupported
311      * @param weeks amount of weeks in this period, which must be zero if unsupported
312      * @param days amount of days in this period, which must be zero if unsupported
313      * @param hours amount of hours in this period, which must be zero if unsupported
314      * @param minutes amount of minutes in this period, which must be zero if unsupported
315      * @param seconds amount of seconds in this period, which must be zero if unsupported
316      * @param millis amount of milliseconds in this period, which must be zero if unsupported
317      * @param type which set of fields this period supports, null means AllType
318      * @throws IllegalArgumentException if an unsupported field's value is non-zero
319      */

320     public Period(int years, int months, int weeks, int days,
321                     int hours, int minutes, int seconds, int millis, PeriodType type) {
322         super(years, months, weeks, days, hours, minutes, seconds, millis, type);
323     }
324
325     /**
326      * Creates a period from the given millisecond duration using the standard
327      * set of fields.
328      * <p>
329      * Only precise fields in the period type will be used.
330      * For the standard period type this is the time fields only.
331      * Thus the year, month, week and day fields will not be populated.
332      * <p>
333      * If the duration is small, less than one day, then this method will perform
334      * as you might expect and split the fields evenly.
335      * <p>
336      * If the duration is larger than one day then all the remaining duration will
337      * be stored in the largest available precise field, hours in this case.
338      * <p>
339      * For example, a duration equal to (365 + 60 + 5) days will be converted to
340      * ((365 + 60 + 5) * 24) hours by this constructor.
341      * <p>
342      * For more control over the conversion process, you have two options:
343      * <ul>
344      * <li>convert the duration to an {@link Interval}, and from there obtain the period
345      * <li>specify a period type that contains precise definitions of the day and larger
346      * fields, such as UTC
347      * </ul>
348      *
349      * @param duration the duration, in milliseconds
350      */

351     public Period(long duration) {
352         super(duration, null, null);
353     }
354
355     /**
356      * Creates a period from the given millisecond duration.
357      * <p>
358      * Only precise fields in the period type will be used.
359      * Imprecise fields will not be populated.
360      * <p>
361      * If the duration is small then this method will perform
362      * as you might expect and split the fields evenly.
363      * <p>
364      * If the duration is large then all the remaining duration will
365      * be stored in the largest available precise field.
366      * For details as to which fields are precise, review the period type javadoc.
367      *
368      * @param duration the duration, in milliseconds
369      * @param type which set of fields this period supports, null means standard
370      */

371     public Period(long duration, PeriodType type) {
372         super(duration, type, null);
373     }
374
375     /**
376      * Creates a period from the given millisecond duration using the standard
377      * set of fields.
378      * <p>
379      * Only precise fields in the period type will be used.
380      * Imprecise fields will not be populated.
381      * <p>
382      * If the duration is small then this method will perform
383      * as you might expect and split the fields evenly.
384      * <p>
385      * If the duration is large then all the remaining duration will
386      * be stored in the largest available precise field.
387      * For details as to which fields are precise, review the period type javadoc.
388      *
389      * @param duration the duration, in milliseconds
390      * @param chronology the chronology to use to split the duration, null means ISO default
391      */

392     public Period(long duration, Chronology chronology) {
393         super(duration, null, chronology);
394     }
395
396     /**
397      * Creates a period from the given millisecond duration.
398      * <p>
399      * Only precise fields in the period type will be used.
400      * Imprecise fields will not be populated.
401      * <p>
402      * If the duration is small then this method will perform
403      * as you might expect and split the fields evenly.
404      * <p>
405      * If the duration is large then all the remaining duration will
406      * be stored in the largest available precise field.
407      * For details as to which fields are precise, review the period type javadoc.
408      *
409      * @param duration the duration, in milliseconds
410      * @param type which set of fields this period supports, null means standard
411      * @param chronology the chronology to use to split the duration, null means ISO default
412      */

413     public Period(long duration, PeriodType type, Chronology chronology) {
414         super(duration, type, chronology);
415     }
416
417     /**
418      * Creates a period from the given interval endpoints using the standard
419      * set of fields.
420      *
421      * @param startInstant interval start, in milliseconds
422      * @param endInstant interval end, in milliseconds
423      */

424     public Period(long startInstant, long endInstant) {
425         super(startInstant, endInstant, null, null);
426     }
427
428     /**
429      * Creates a period from the given interval endpoints.
430      *
431      * @param startInstant interval start, in milliseconds
432      * @param endInstant interval end, in milliseconds
433      * @param type which set of fields this period supports, null means standard
434      */

435     public Period(long startInstant, long endInstant, PeriodType type) {
436         super(startInstant, endInstant, type, null);
437     }
438
439     /**
440      * Creates a period from the given interval endpoints using the standard
441      * set of fields.
442      *
443      * @param startInstant interval start, in milliseconds
444      * @param endInstant interval end, in milliseconds
445      * @param chrono the chronology to use, null means ISO in default zone
446      */

447     public Period(long startInstant, long endInstant, Chronology chrono) {
448         super(startInstant, endInstant, null, chrono);
449     }
450
451     /**
452      * Creates a period from the given interval endpoints.
453      *
454      * @param startInstant interval start, in milliseconds
455      * @param endInstant interval end, in milliseconds
456      * @param type which set of fields this period supports, null means standard
457      * @param chrono the chronology to use, null means ISO in default zone
458      */

459     public Period(long startInstant, long endInstant, PeriodType type, Chronology chrono) {
460         super(startInstant, endInstant, type, chrono);
461     }
462
463     /**
464      * Creates a period from the given interval endpoints using the standard
465      * set of fields.
466      *
467      * @param startInstant interval start, null means now
468      * @param endInstant interval end, null means now
469      */

470     public Period(ReadableInstant startInstant, ReadableInstant endInstant) {
471         super(startInstant, endInstant, null);
472     }
473
474     /**
475      * Creates a period from the given interval endpoints.
476      *
477      * @param startInstant interval start, null means now
478      * @param endInstant interval end, null means now
479      * @param type which set of fields this period supports, null means standard
480      */

481     public Period(ReadableInstant startInstant, ReadableInstant endInstant, PeriodType type) {
482         super(startInstant, endInstant, type);
483     }
484
485     /**
486      * Creates a period from two partially specified times.
487      * <p>
488      * The two partials must contain the same fields, thus you can specify
489      * two <code>LocalDate</code> objects, or two <code>LocalTime</code> objects,
490      * but not one of each.
491      * As these are Partial objects, time zones have no effect on the result.
492      * <p>
493      * The two partials must also both be contiguous - see
494      * {@link DateTimeUtils#isContiguous(ReadablePartial)} for a definition.
495      * Both <code>LocalDate</code> and <code>LocalTime</code> are contiguous.
496      * <p>
497      * An alternative way of constructing a Period from two Partials
498      * is {@link #fieldDifference(ReadablePartial, ReadablePartial)}.
499      * That method handles all kinds of partials.
500      *
501      * @param start the start of the period, must not be null
502      * @param end the end of the period, must not be null
503      * @throws IllegalArgumentException if the partials are null or invalid
504      * @since 1.1
505      */

506     public Period(ReadablePartial start, ReadablePartial end) {
507         super(start, end, null);
508     }
509
510     /**
511      * Creates a period from two partially specified times.
512      * <p>
513      * The two partials must contain the same fields, thus you can specify
514      * two <code>LocalDate</code> objects, or two <code>LocalTime</code> objects,
515      * but not one of each.
516      * As these are Partial objects, time zones have no effect on the result.
517      * <p>
518      * The two partials must also both be contiguous - see
519      * {@link DateTimeUtils#isContiguous(ReadablePartial)} for a definition.
520      * Both <code>LocalDate</code> and <code>LocalTime</code> are contiguous.
521      * <p>
522      * An alternative way of constructing a Period from two Partials
523      * is {@link #fieldDifference(ReadablePartial, ReadablePartial)}.
524      * That method handles all kinds of partials.
525      *
526      * @param start the start of the period, must not be null
527      * @param end the end of the period, must not be null
528      * @param type which set of fields this period supports, null means standard
529      * @throws IllegalArgumentException if the partials are null or invalid
530      * @since 1.1
531      */

532     public Period(ReadablePartial start, ReadablePartial end, PeriodType type) {
533         super(start, end, type);
534     }
535
536     /**
537      * Creates a period from the given start point and the duration.
538      *
539      * @param startInstant the interval start, null means now
540      * @param duration the duration of the interval, null means zero-length
541      */

542     public Period(ReadableInstant startInstant, ReadableDuration duration) {
543         super(startInstant, duration, null);
544     }
545
546     /**
547      * Creates a period from the given start point and the duration.
548      *
549      * @param startInstant the interval start, null means now
550      * @param duration the duration of the interval, null means zero-length
551      * @param type which set of fields this period supports, null means standard
552      */

553     public Period(ReadableInstant startInstant, ReadableDuration duration, PeriodType type) {
554         super(startInstant, duration, type);
555     }
556
557     /**
558      * Creates a period from the given duration and end point.
559      *
560      * @param duration the duration of the interval, null means zero-length
561      * @param endInstant the interval end, null means now
562      */

563     public Period(ReadableDuration duration, ReadableInstant endInstant) {
564         super(duration, endInstant, null);
565     }
566
567     /**
568      * Creates a period from the given duration and end point.
569      *
570      * @param duration the duration of the interval, null means zero-length
571      * @param endInstant the interval end, null means now
572      * @param type which set of fields this period supports, null means standard
573      */

574     public Period(ReadableDuration duration, ReadableInstant endInstant, PeriodType type) {
575         super(duration, endInstant, type);
576     }
577
578     /**
579      * Creates a period from the specified object using the
580      * {@link org.joda.time.convert.ConverterManager ConverterManager}.
581      *
582      * @param period period to convert
583      * @throws IllegalArgumentException if period is invalid
584      * @throws UnsupportedOperationException if an unsupported field's value is non-zero
585      */

586     public Period(Object JavaDoc period) {
587         super(period, null, null);
588     }
589
590     /**
591      * Creates a period from the specified object using the
592      * {@link org.joda.time.convert.ConverterManager ConverterManager}.
593      *
594      * @param period period to convert
595      * @param type which set of fields this period supports, null means use converter
596      * @throws IllegalArgumentException if period is invalid
597      * @throws UnsupportedOperationException if an unsupported field's value is non-zero
598      */

599     public Period(Object JavaDoc period, PeriodType type) {
600         super(period, type, null);
601     }
602
603     /**
604      * Creates a period from the specified object using the
605      * {@link org.joda.time.convert.ConverterManager ConverterManager}.
606      *
607      * @param period period to convert
608      * @param chrono the chronology to use, null means ISO in default zone
609      * @throws IllegalArgumentException if period is invalid
610      * @throws UnsupportedOperationException if an unsupported field's value is non-zero
611      */

612     public Period(Object JavaDoc period, Chronology chrono) {
613         super(period, null, chrono);
614     }
615
616     /**
617      * Creates a period from the specified object using the
618      * {@link org.joda.time.convert.ConverterManager ConverterManager}.
619      *
620      * @param period period to convert
621      * @param type which set of fields this period supports, null means use converter
622      * @param chrono the chronology to use, null means ISO in default zone
623      * @throws IllegalArgumentException if period is invalid
624      * @throws UnsupportedOperationException if an unsupported field's value is non-zero
625      */

626     public Period(Object JavaDoc period, PeriodType type, Chronology chrono) {
627         super(period, type, chrono);
628     }
629
630     /**
631      * Constructor used when we trust ourselves.
632      *
633      * @param values the values to use, not null, not cloned
634      * @param type which set of fields this period supports, not null
635      */

636     private Period(int[] values, PeriodType type) {
637         super(values, type);
638     }
639
640     //-----------------------------------------------------------------------
641
/**
642      * Get this period as an immutable <code>Period</code> object
643      * by returning <code>this</code>.
644      *
645      * @return <code>this</code>
646      */

647     public Period toPeriod() {
648         return this;
649     }
650
651     //-----------------------------------------------------------------------
652
/**
653      * Gets the years field part of the period.
654      *
655      * @return the number of years in the period, zero if unsupported
656      */

657     public int getYears() {
658         return getPeriodType().getIndexedField(this, PeriodType.YEAR_INDEX);
659     }
660
661     /**
662      * Gets the months field part of the period.
663      *
664      * @return the number of months in the period, zero if unsupported
665      */

666     public int getMonths() {
667         return getPeriodType().getIndexedField(this, PeriodType.MONTH_INDEX);
668     }
669
670     /**
671      * Gets the weeks field part of the period.
672      *
673      * @return the number of weeks in the period, zero if unsupported
674      */

675     public int getWeeks() {
676         return getPeriodType().getIndexedField(this, PeriodType.WEEK_INDEX);
677     }
678
679     /**
680      * Gets the days field part of the period.
681      *
682      * @return the number of days in the period, zero if unsupported
683      */

684     public int getDays() {
685         return getPeriodType().getIndexedField(this, PeriodType.DAY_INDEX);
686     }
687
688     //-----------------------------------------------------------------------
689
/**
690      * Gets the hours field part of the period.
691      *
692      * @return the number of hours in the period, zero if unsupported
693      */

694     public int getHours() {
695         return getPeriodType().getIndexedField(this, PeriodType.HOUR_INDEX);
696     }
697
698     /**
699      * Gets the minutes field part of the period.
700      *
701      * @return the number of minutes in the period, zero if unsupported
702      */

703     public int getMinutes() {
704         return getPeriodType().getIndexedField(this, PeriodType.MINUTE_INDEX);
705     }
706
707     /**
708      * Gets the seconds field part of the period.
709      *
710      * @return the number of seconds in the period, zero if unsupported
711      */

712     public int getSeconds() {
713         return getPeriodType().getIndexedField(this, PeriodType.SECOND_INDEX);
714     }
715
716     /**
717      * Gets the millis field part of the period.
718      *
719      * @return the number of millis in the period, zero if unsupported
720      */

721     public int getMillis() {
722         return getPeriodType().getIndexedField(this, PeriodType.MILLI_INDEX);
723     }
724
725     //-----------------------------------------------------------------------
726
/**
727      * Creates a new Period instance with the same field values but
728      * different PeriodType.
729      * <p>
730      * This period instance is immutable and unaffected by this method call.
731      *
732      * @param type the period type to use, null means standard
733      * @return the new period instance
734      * @throws IllegalArgumentException if the new period won't accept all of the current fields
735      */

736     public Period withPeriodType(PeriodType type) {
737         type = DateTimeUtils.getPeriodType(type);
738         if (type.equals(getPeriodType())) {
739             return this;
740         }
741         return new Period(this, type);
742     }
743
744     /**
745      * Creates a new Period instance with the fields from the specified period
746      * copied on top of those from this period.
747      * <p>
748      * This period instance is immutable and unaffected by this method call.
749      *
750      * @param period the period to copy from, null ignored
751      * @return the new period instance
752      * @throws IllegalArgumentException if a field type is unsupported
753      */

754     public Period withFields(ReadablePeriod period) {
755         if (period == null) {
756             return this;
757         }
758         int[] newValues = getValues(); // cloned
759
newValues = super.mergePeriodInto(newValues, period);
760         return new Period(newValues, getPeriodType());
761     }
762
763     //-----------------------------------------------------------------------
764
/**
765      * Creates a new Period instance with the specified field set to a new value.
766      * <p>
767      * This period instance is immutable and unaffected by this method call.
768      *
769      * @param field the field to set, not null
770      * @param value the value to set to
771      * @return the new period instance
772      * @throws IllegalArgumentException if the field type is null or unsupported
773      */

774     public Period withField(DurationFieldType field, int value) {
775         if (field == null) {
776             throw new IllegalArgumentException JavaDoc("Field must not be null");
777         }
778         int[] newValues = getValues(); // cloned
779
super.setFieldInto(newValues, field, value);
780         return new Period(newValues, getPeriodType());
781     }
782
783     /**
784      * Creates a new Period instance with the valueToAdd added to the specified field.
785      * <p>
786      * This period instance is immutable and unaffected by this method call.
787      *
788      * @param field the field to set, not null
789      * @param value the value to add
790      * @return the new period instance
791      * @throws IllegalArgumentException if the field type is null or unsupported
792      */

793     public Period withFieldAdded(DurationFieldType field, int value) {
794         if (field == null) {
795             throw new IllegalArgumentException JavaDoc("Field must not be null");
796         }
797         if (value == 0) {
798             return this;
799         }
800         int[] newValues = getValues(); // cloned
801
super.addFieldInto(newValues, field, value);
802         return new Period(newValues, getPeriodType());
803     }
804
805     //-----------------------------------------------------------------------
806
/**
807      * Returns a new period with the specified number of years.
808      * <p>
809      * This period instance is immutable and unaffected by this method call.
810      *
811      * @param years the amount of years to add, may be negative
812      * @return the new period with the increased years
813      * @throws UnsupportedOperationException if the field is not supported
814      */

815     public Period withYears(int years) {
816         int[] values = getValues(); // cloned
817
getPeriodType().setIndexedField(this, PeriodType.YEAR_INDEX, values, years);
818         return new Period(values, getPeriodType());
819     }
820
821     /**
822      * Returns a new period with the specified number of months.
823      * <p>
824      * This period instance is immutable and unaffected by this method call.
825      *
826      * @param months the amount of months to add, may be negative
827      * @return the new period with the increased months
828      * @throws UnsupportedOperationException if the field is not supported
829      */

830     public Period withMonths(int months) {
831         int[] values = getValues(); // cloned
832
getPeriodType().setIndexedField(this, PeriodType.MONTH_INDEX, values, months);
833         return new Period(values, getPeriodType());
834     }
835
836     /**
837      * Returns a new period with the specified number of weeks.
838      * <p>
839      * This period instance is immutable and unaffected by this method call.
840      *
841      * @param weeks the amount of weeks to add, may be negative
842      * @return the new period with the increased weeks
843      * @throws UnsupportedOperationException if the field is not supported
844      */

845     public Period withWeeks(int weeks) {
846         int[] values = getValues(); // cloned
847
getPeriodType().setIndexedField(this, PeriodType.WEEK_INDEX, values, weeks);
848         return new Period(values, getPeriodType());
849     }
850
851     /**
852      * Returns a new period with the specified number of days.
853      * <p>
854      * This period instance is immutable and unaffected by this method call.
855      *
856      * @param days the amount of days to add, may be negative
857      * @return the new period with the increased days
858      * @throws UnsupportedOperationException if the field is not supported
859      */

860     public Period withDays(int days) {
861         int[] values = getValues(); // cloned
862
getPeriodType().setIndexedField(this, PeriodType.DAY_INDEX, values, days);
863         return new Period(values, getPeriodType());
864     }
865
866     /**
867      * Returns a new period with the specified number of hours.
868      * <p>
869      * This period instance is immutable and unaffected by this method call.
870      *
871      * @param hours the amount of hours to add, may be negative
872      * @return the new period with the increased hours
873      * @throws UnsupportedOperationException if the field is not supported
874      */

875     public Period withHours(int hours) {
876         int[] values = getValues(); // cloned
877
getPeriodType().setIndexedField(this, PeriodType.HOUR_INDEX, values, hours);
878         return new Period(values, getPeriodType());
879     }
880
881     /**
882      * Returns a new period with the specified number of minutes.
883      * <p>
884      * This period instance is immutable and unaffected by this method call.
885      *
886      * @param minutes the amount of minutes to add, may be negative
887      * @return the new period with the increased minutes
888      * @throws UnsupportedOperationException if the field is not supported
889      */

890     public Period withMinutes(int minutes) {
891         int[] values = getValues(); // cloned
892
getPeriodType().setIndexedField(this, PeriodType.MINUTE_INDEX, values, minutes);
893         return new Period(values, getPeriodType());
894     }
895
896     /**
897      * Returns a new period with the specified number of seconds.
898      * <p>
899      * This period instance is immutable and unaffected by this method call.
900      *
901      * @param seconds the amount of seconds to add, may be negative
902      * @return the new period with the increased seconds
903      * @throws UnsupportedOperationException if the field is not supported
904      */

905     public Period withSeconds(int seconds) {
906         int[] values = getValues(); // cloned
907
getPeriodType().setIndexedField(this, PeriodType.SECOND_INDEX, values, seconds);
908         return new Period(values, getPeriodType());
909     }
910
911     /**
912      * Returns a new period with the specified number of millis.
913      * <p>
914      * This period instance is immutable and unaffected by this method call.
915      *
916      * @param millis the amount of millis to add, may be negative
917      * @return the new period with the increased millis
918      * @throws UnsupportedOperationException if the field is not supported
919      */

920     public Period withMillis(int millis) {
921         int[] values = getValues(); // cloned
922
getPeriodType().setIndexedField(this, PeriodType.MILLI_INDEX, values, millis);
923         return new Period(values, getPeriodType());
924     }
925
926     //-----------------------------------------------------------------------
927
/**
928      * Returns a new period with the specified number of years added.
929      * <p>
930      * This period instance is immutable and unaffected by this method call.
931      *
932      * @param years the amount of years to add, may be negative
933      * @return the new period with the increased years
934      * @throws UnsupportedOperationException if the field is not supported
935      */

936     public Period plusYears(int years) {
937         if (years == 0) {
938             return this;
939         }
940         int[] values = getValues(); // cloned
941
getPeriodType().addIndexedField(this, PeriodType.YEAR_INDEX, values, years);
942         return new Period(values, getPeriodType());
943     }
944
945     /**
946      * Returns a new period plus the specified number of months added.
947      * <p>
948      * This period instance is immutable and unaffected by this method call.
949      *
950      * @param months the amount of months to add, may be negative
951      * @return the new period plus the increased months
952      * @throws UnsupportedOperationException if the field is not supported
953      */

954     public Period plusMonths(int months) {
955         if (months == 0) {
956             return this;
957         }
958         int[] values = getValues(); // cloned
959
getPeriodType().addIndexedField(this, PeriodType.MONTH_INDEX, values, months);
960         return new Period(values, getPeriodType());
961     }
962
963     /**
964      * Returns a new period plus the specified number of weeks added.
965      * <p>
966      * This period instance is immutable and unaffected by this method call.
967      *
968      * @param weeks the amount of weeks to add, may be negative
969      * @return the new period plus the increased weeks
970      * @throws UnsupportedOperationException if the field is not supported
971      */

972     public Period plusWeeks(int weeks) {
973         if (weeks == 0) {
974             return this;
975         }
976         int[] values = getValues(); // cloned
977
getPeriodType().addIndexedField(this, PeriodType.WEEK_INDEX, values, weeks);
978         return new Period(values, getPeriodType());
979     }
980
981     /**
982      * Returns a new period plus the specified number of days added.
983      * <p>
984      * This period instance is immutable and unaffected by this method call.
985      *
986      * @param days the amount of days to add, may be negative
987      * @return the new period plus the increased days
988      * @throws UnsupportedOperationException if the field is not supported
989      */

990     public Period plusDays(int days) {
991         if (days == 0) {
992             return this;
993         }
994         int[] values = getValues(); // cloned
995
getPeriodType().addIndexedField(this, PeriodType.DAY_INDEX, values, days);
996         return new Period(values, getPeriodType());
997     }
998
999     /**
1000     * Returns a new period plus the specified number of hours added.
1001     * <p>
1002     * This period instance is immutable and unaffected by this method call.
1003     *
1004     * @param hours the amount of hours to add, may be negative
1005     * @return the new period plus the increased hours
1006     * @throws UnsupportedOperationException if the field is not supported
1007     */

1008    public Period plusHours(int hours) {
1009        if (hours == 0) {
1010            return this;
1011        }
1012        int[] values = getValues(); // cloned
1013
getPeriodType().addIndexedField(this, PeriodType.HOUR_INDEX, values, hours);
1014        return new Period(values, getPeriodType());
1015    }
1016
1017    /**
1018     * Returns a new period plus the specified number of minutes added.
1019     * <p>
1020     * This period instance is immutable and unaffected by this method call.
1021     *
1022     * @param minutes the amount of minutes to add, may be negative
1023     * @return the new period plus the increased minutes
1024     * @throws UnsupportedOperationException if the field is not supported
1025     */

1026    public Period plusMinutes(int minutes) {
1027        if (minutes == 0) {
1028            return this;
1029        }
1030        int[] values = getValues(); // cloned
1031
getPeriodType().addIndexedField(this, PeriodType.MINUTE_INDEX, values, minutes);
1032        return new Period(values, getPeriodType());
1033    }
1034
1035    /**
1036     * Returns a new period plus the specified number of seconds added.
1037     * <p>
1038     * This period instance is immutable and unaffected by this method call.
1039     *
1040     * @param seconds the amount of seconds to add, may be negative
1041     * @return the new period plus the increased seconds
1042     * @throws UnsupportedOperationException if the field is not supported
1043     */

1044    public Period plusSeconds(int seconds) {
1045        if (seconds == 0) {
1046            return this;
1047        }
1048        int[] values = getValues(); // cloned
1049
getPeriodType().addIndexedField(this, PeriodType.SECOND_INDEX, values, seconds);
1050        return new Period(values, getPeriodType());
1051    }
1052
1053    /**
1054     * Returns a new period plus the specified number of millis added.
1055     * <p>
1056     * This period instance is immutable and unaffected by this method call.
1057     *
1058     * @param millis the amount of millis to add, may be negative
1059     * @return the new period plus the increased millis
1060     * @throws UnsupportedOperationException if the field is not supported
1061     */

1062    public Period plusMillis(int millis) {
1063        if (millis == 0) {
1064            return this;
1065        }
1066        int[] values = getValues(); // cloned
1067
getPeriodType().addIndexedField(this, PeriodType.MILLI_INDEX, values, millis);
1068        return new Period(values, getPeriodType());
1069    }
1070
1071    //-----------------------------------------------------------------------
1072
/**
1073     * Returns a new period with the specified number of years taken away.
1074     * <p>
1075     * This period instance is immutable and unaffected by this method call.
1076     *
1077     * @param years the amount of years to take away, may be negative
1078     * @return the new period with the increased years
1079     * @throws UnsupportedOperationException if the field is not supported
1080     */

1081    public Period minusYears(int years) {
1082        return plusYears(-years);
1083    }
1084
1085    /**
1086     * Returns a new period minus the specified number of months taken away.
1087     * <p>
1088     * This period instance is immutable and unaffected by this method call.
1089     *
1090     * @param months the amount of months to take away, may be negative
1091     * @return the new period minus the increased months
1092     * @throws UnsupportedOperationException if the field is not supported
1093     */

1094    public Period minusMonths(int months) {
1095        return plusMonths(-months);
1096    }
1097
1098    /**
1099     * Returns a new period minus the specified number of weeks taken away.
1100     * <p>
1101     * This period instance is immutable and unaffected by this method call.
1102     *
1103     * @param weeks the amount of weeks to take away, may be negative
1104     * @return the new period minus the increased weeks
1105     * @throws UnsupportedOperationException if the field is not supported
1106     */

1107    public Period minusWeeks(int weeks) {
1108        return plusWeeks(-weeks);
1109    }
1110
1111    /**
1112     * Returns a new period minus the specified number of days taken away.
1113     * <p>
1114     * This period instance is immutable and unaffected by this method call.
1115     *
1116     * @param days the amount of days to take away, may be negative
1117     * @return the new period minus the increased days
1118     * @throws UnsupportedOperationException if the field is not supported
1119     */

1120    public Period minusDays(int days) {
1121        return plusDays(-days);
1122    }
1123
1124    /**
1125     * Returns a new period minus the specified number of hours taken away.
1126     * <p>
1127     * This period instance is immutable and unaffected by this method call.
1128     *
1129     * @param hours the amount of hours to take away, may be negative
1130     * @return the new period minus the increased hours
1131     * @throws UnsupportedOperationException if the field is not supported
1132     */

1133    public Period minusHours(int hours) {
1134        return plusHours(-hours);
1135    }
1136
1137    /**
1138     * Returns a new period minus the specified number of minutes taken away.
1139     * <p>
1140     * This period instance is immutable and unaffected by this method call.
1141     *
1142     * @param minutes the amount of minutes to take away, may be negative
1143     * @return the new period minus the increased minutes
1144     * @throws UnsupportedOperationException if the field is not supported
1145     */

1146    public Period minusMinutes(int minutes) {
1147        return plusMinutes(-minutes);
1148    }
1149
1150    /**
1151     * Returns a new period minus the specified number of seconds taken away.
1152     * <p>
1153     * This period instance is immutable and unaffected by this method call.
1154     *
1155     * @param seconds the amount of seconds to take away, may be negative
1156     * @return the new period minus the increased seconds
1157     * @throws UnsupportedOperationException if the field is not supported
1158     */

1159    public Period minusSeconds(int seconds) {
1160        return plusSeconds(-seconds);
1161    }
1162
1163    /**
1164     * Returns a new period minus the specified number of millis taken away.
1165     * <p>
1166     * This period instance is immutable and unaffected by this method call.
1167     *
1168     * @param millis the amount of millis to take away, may be negative
1169     * @return the new period minus the increased millis
1170     * @throws UnsupportedOperationException if the field is not supported
1171     */

1172    public Period minusMillis(int millis) {
1173        return plusMillis(-millis);
1174    }
1175
1176}
1177
Popular Tags