EMMA Coverage Report (generated Tue Oct 28 00:01:11 GMT 2008)
[all classes][org.joda.time]

COVERAGE SUMMARY FOR SOURCE FILE [Period.java]

nameclass, %method, %block, %line, %
Period.java100% (1/1)100% (83/83)100% (1708/1708)100% (273/273)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Period100% (1/1)100% (83/83)100% (1708/1708)100% (273/273)
<static initializer> 100% (1/1)100% (5/5)100% (1/1)
Period (): void 100% (1/1)100% (6/6)100% (2/2)
Period (Object): void 100% (1/1)100% (6/6)100% (2/2)
Period (Object, Chronology): void 100% (1/1)100% (6/6)100% (2/2)
Period (Object, PeriodType): void 100% (1/1)100% (6/6)100% (2/2)
Period (Object, PeriodType, Chronology): void 100% (1/1)100% (6/6)100% (2/2)
Period (ReadableDuration, ReadableInstant): void 100% (1/1)100% (6/6)100% (2/2)
Period (ReadableDuration, ReadableInstant, PeriodType): void 100% (1/1)100% (6/6)100% (2/2)
Period (ReadableInstant, ReadableDuration): void 100% (1/1)100% (6/6)100% (2/2)
Period (ReadableInstant, ReadableDuration, PeriodType): void 100% (1/1)100% (6/6)100% (2/2)
Period (ReadableInstant, ReadableInstant): void 100% (1/1)100% (6/6)100% (2/2)
Period (ReadableInstant, ReadableInstant, PeriodType): void 100% (1/1)100% (6/6)100% (2/2)
Period (ReadablePartial, ReadablePartial): void 100% (1/1)100% (6/6)100% (2/2)
Period (ReadablePartial, ReadablePartial, PeriodType): void 100% (1/1)100% (6/6)100% (2/2)
Period (int [], PeriodType): void 100% (1/1)100% (5/5)100% (2/2)
Period (int, int, int, int): void 100% (1/1)100% (12/12)100% (2/2)
Period (int, int, int, int, int, int, int, int): void 100% (1/1)100% (12/12)100% (2/2)
Period (int, int, int, int, int, int, int, int, PeriodType): void 100% (1/1)100% (12/12)100% (2/2)
Period (long): void 100% (1/1)100% (6/6)100% (2/2)
Period (long, Chronology): void 100% (1/1)100% (6/6)100% (2/2)
Period (long, PeriodType): void 100% (1/1)100% (6/6)100% (2/2)
Period (long, PeriodType, Chronology): void 100% (1/1)100% (6/6)100% (2/2)
Period (long, long): void 100% (1/1)100% (7/7)100% (2/2)
Period (long, long, Chronology): void 100% (1/1)100% (7/7)100% (2/2)
Period (long, long, PeriodType): void 100% (1/1)100% (7/7)100% (2/2)
Period (long, long, PeriodType, Chronology): void 100% (1/1)100% (7/7)100% (2/2)
checkYearsAndMonths (String): void 100% (1/1)100% (35/35)100% (5/5)
days (int): Period 100% (1/1)100% (39/39)100% (1/1)
fieldDifference (ReadablePartial, ReadablePartial): Period 100% (1/1)100% (89/89)100% (14/14)
getDays (): int 100% (1/1)100% (6/6)100% (1/1)
getHours (): int 100% (1/1)100% (6/6)100% (1/1)
getMillis (): int 100% (1/1)100% (6/6)100% (1/1)
getMinutes (): int 100% (1/1)100% (6/6)100% (1/1)
getMonths (): int 100% (1/1)100% (6/6)100% (1/1)
getSeconds (): int 100% (1/1)100% (6/6)100% (1/1)
getWeeks (): int 100% (1/1)100% (6/6)100% (1/1)
getYears (): int 100% (1/1)100% (6/6)100% (1/1)
hours (int): Period 100% (1/1)100% (39/39)100% (1/1)
millis (int): Period 100% (1/1)100% (39/39)100% (1/1)
minus (ReadablePeriod): Period 100% (1/1)100% (102/102)100% (12/12)
minusDays (int): Period 100% (1/1)100% (5/5)100% (1/1)
minusHours (int): Period 100% (1/1)100% (5/5)100% (1/1)
minusMillis (int): Period 100% (1/1)100% (5/5)100% (1/1)
minusMinutes (int): Period 100% (1/1)100% (5/5)100% (1/1)
minusMonths (int): Period 100% (1/1)100% (5/5)100% (1/1)
minusSeconds (int): Period 100% (1/1)100% (5/5)100% (1/1)
minusWeeks (int): Period 100% (1/1)100% (5/5)100% (1/1)
minusYears (int): Period 100% (1/1)100% (5/5)100% (1/1)
minutes (int): Period 100% (1/1)100% (39/39)100% (1/1)
months (int): Period 100% (1/1)100% (39/39)100% (1/1)
normalizedStandard (): Period 100% (1/1)100% (4/4)100% (1/1)
normalizedStandard (PeriodType): Period 100% (1/1)100% (86/86)100% (17/17)
plus (ReadablePeriod): Period 100% (1/1)100% (94/94)100% (12/12)
plusDays (int): Period 100% (1/1)100% (22/22)100% (5/5)
plusHours (int): Period 100% (1/1)100% (22/22)100% (5/5)
plusMillis (int): Period 100% (1/1)100% (22/22)100% (5/5)
plusMinutes (int): Period 100% (1/1)100% (22/22)100% (5/5)
plusMonths (int): Period 100% (1/1)100% (22/22)100% (5/5)
plusSeconds (int): Period 100% (1/1)100% (22/22)100% (5/5)
plusWeeks (int): Period 100% (1/1)100% (22/22)100% (5/5)
plusYears (int): Period 100% (1/1)100% (22/22)100% (5/5)
seconds (int): Period 100% (1/1)100% (39/39)100% (1/1)
toPeriod (): Period 100% (1/1)100% (2/2)100% (1/1)
toStandardDays (): Days 100% (1/1)100% (53/53)100% (9/9)
toStandardDuration (): Duration 100% (1/1)100% (52/52)100% (8/8)
toStandardHours (): Hours 100% (1/1)100% (53/53)100% (9/9)
toStandardMinutes (): Minutes 100% (1/1)100% (53/53)100% (9/9)
toStandardSeconds (): Seconds 100% (1/1)100% (51/51)100% (8/8)
toStandardWeeks (): Weeks 100% (1/1)100% (51/51)100% (8/8)
weeks (int): Period 100% (1/1)100% (39/39)100% (1/1)
withDays (int): Period 100% (1/1)100% (18/18)100% (3/3)
withField (DurationFieldType, int): Period 100% (1/1)100% (22/22)100% (5/5)
withFieldAdded (DurationFieldType, int): Period 100% (1/1)100% (26/26)100% (7/7)
withFields (ReadablePeriod): Period 100% (1/1)100% (19/19)100% (5/5)
withHours (int): Period 100% (1/1)100% (18/18)100% (3/3)
withMillis (int): Period 100% (1/1)100% (18/18)100% (3/3)
withMinutes (int): Period 100% (1/1)100% (18/18)100% (3/3)
withMonths (int): Period 100% (1/1)100% (18/18)100% (3/3)
withPeriodType (PeriodType): Period 100% (1/1)100% (16/16)100% (4/4)
withSeconds (int): Period 100% (1/1)100% (18/18)100% (3/3)
withWeeks (int): Period 100% (1/1)100% (18/18)100% (3/3)
withYears (int): Period 100% (1/1)100% (18/18)100% (3/3)
years (int): Period 100% (1/1)100% (43/43)100% (1/1)

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 */
16package org.joda.time;
17 
18import java.io.Serializable;
19 
20import org.joda.time.base.BasePeriod;
21import org.joda.time.chrono.ISOChronology;
22import org.joda.time.field.FieldUtils;
23import org.joda.time.format.ISOPeriodFormat;
24 
25/**
26 * An immutable time period specifying a set of duration field values.
27 * <p>
28 * A time period is divided into a number of fields, such as hours and seconds.
29 * Which fields are supported is defined by the PeriodType class.
30 * The default is the standard period type, which supports years, months, weeks, days,
31 * hours, minutes, seconds and millis.
32 * <p>
33 * When this time period is added to an instant, the effect is of adding each field in turn.
34 * As a result, this takes into account daylight savings time.
35 * Adding a time period of 1 day to the day before daylight savings starts will only add
36 * 23 hours rather than 24 to ensure that the time remains the same.
37 * If this is not the behaviour you want, then see {@link Duration}.
38 * <p>
39 * The definition of a period also affects the equals method. A period of 1
40 * day is not equal to a period of 24 hours, nor 1 hour equal to 60 minutes.
41 * This is because periods represent an abstracted definition of a time period
42 * (eg. a day may not actually be 24 hours, it might be 23 or 25 at daylight
43 * savings boundary). To compare the actual duration of two periods, convert
44 * both to durations using toDuration, an operation that emphasises that the
45 * result may differ according to the date you choose.
46 * <p>
47 * Period is thread-safe and immutable, provided that the PeriodType is as well.
48 * All standard PeriodType classes supplied are thread-safe and immutable.
49 *
50 * @author Brian S O'Neill
51 * @author Stephen Colebourne
52 * @since 1.0
53 * @see MutablePeriod
54 */
55public final class Period
56        extends BasePeriod
57        implements ReadablePeriod, Serializable {
58 
59    /**
60     * A period of zero length and standard period type.
61     * @since 1.4
62     */
63    public static final Period ZERO = new Period();
64 
65    /** Serialization version */
66    private static final long serialVersionUID = 741052353876488155L;
67 
68    //-----------------------------------------------------------------------
69    /**
70     * Create a period with a specified number of years.
71     * <p>
72     * The standard period type is used, thus you can add other fields such
73     * as months or days using the <code>withXxx()</code> methods.
74     * For example, <code>Period.years(2).withMonths(6);</code>
75     * <p>
76     * If you want a year-based period that cannot have other fields added,
77     * then you should consider using {@link Years}.
78     *
79     * @param years  the amount of years in this period
80     * @return the period
81     */
82    public static Period years(int years) {
83        return new Period(new int[] {years, 0, 0, 0, 0, 0, 0, 0, 0}, PeriodType.standard());
84    }
85 
86    /**
87     * Create a period with a specified number of months.
88     * <p>
89     * The standard period type is used, thus you can add other fields such
90     * as years or days using the <code>withXxx()</code> methods.
91     * For example, <code>Period.months(2).withDays(6);</code>
92     * <p>
93     * If you want a month-based period that cannot have other fields added,
94     * then you should consider using {@link Months}.
95     *
96     * @param months  the amount of months in this period
97     * @return the period
98     */
99    public static Period months(int months) {
100        return new Period(new int[] {0, months, 0, 0, 0, 0, 0, 0}, PeriodType.standard());
101    }
102 
103    /**
104     * Create a period with a specified number of weeks.
105     * <p>
106     * The standard period type is used, thus you can add other fields such
107     * as months or days using the <code>withXxx()</code> methods.
108     * For example, <code>Period.weeks(2).withDays(6);</code>
109     * <p>
110     * If you want a week-based period that cannot have other fields added,
111     * then you should consider using {@link Weeks}.
112     *
113     * @param weeks  the amount of weeks in this period
114     * @return the period
115     */
116    public static Period weeks(int weeks) {
117        return new Period(new int[] {0, 0, weeks, 0, 0, 0, 0, 0}, PeriodType.standard());
118    }
119 
120    /**
121     * Create a period with a specified number of days.
122     * <p>
123     * The standard period type is used, thus you can add other fields such
124     * as months or weeks using the <code>withXxx()</code> methods.
125     * For example, <code>Period.days(2).withHours(6);</code>
126     * <p>
127     * If you want a day-based period that cannot have other fields added,
128     * then you should consider using {@link Days}.
129     *
130     * @param days  the amount of days in this period
131     * @return the period
132     */
133    public static Period days(int days) {
134        return new Period(new int[] {0, 0, 0, days, 0, 0, 0, 0}, PeriodType.standard());
135    }
136 
137    /**
138     * Create a period with a specified number of hours.
139     * <p>
140     * The standard period type is used, thus you can add other fields such
141     * as months or days using the <code>withXxx()</code> methods.
142     * For example, <code>Period.hours(2).withMinutes(30);</code>
143     * <p>
144     * If you want a hour-based period that cannot have other fields added,
145     * then you should consider using {@link Hours}.
146     *
147     * @param hours  the amount of hours in this period
148     * @return the period
149     */
150    public static Period hours(int hours) {
151        return new Period(new int[] {0, 0, 0, 0, hours, 0, 0, 0}, PeriodType.standard());
152    }
153 
154    /**
155     * Create a period with a specified number of minutes.
156     * <p>
157     * The standard period type is used, thus you can add other fields such
158     * as days or hours using the <code>withXxx()</code> methods.
159     * For example, <code>Period.minutes(2).withSeconds(30);</code>
160     * <p>
161     * If you want a minute-based period that cannot have other fields added,
162     * then you should consider using {@link Minutes}.
163     *
164     * @param minutes  the amount of minutes in this period
165     * @return the period
166     */
167    public static Period minutes(int minutes) {
168        return new Period(new int[] {0, 0, 0, 0, 0, minutes, 0, 0}, PeriodType.standard());
169    }
170 
171    /**
172     * Create a period with a specified number of seconds.
173     * <p>
174     * The standard period type is used, thus you can add other fields such
175     * as days or hours using the <code>withXxx()</code> methods.
176     * For example, <code>Period.seconds(2).withMillis(30);</code>
177     * <p>
178     * If you want a second-based period that cannot have other fields added,
179     * then you should consider using {@link Seconds}.
180     *
181     * @param seconds  the amount of seconds in this period
182     * @return the period
183     */
184    public static Period seconds(int seconds) {
185        return new Period(new int[] {0, 0, 0, 0, 0, 0, seconds, 0}, PeriodType.standard());
186    }
187 
188    /**
189     * Create a period with a specified number of millis.
190     * <p>
191     * The standard period type is used, thus you can add other fields such
192     * as days or hours using the <code>withXxx()</code> methods.
193     * For example, <code>Period.millis(20).withSeconds(30);</code>
194     *
195     * @param millis  the amount of millis in this period
196     * @return the period
197     */
198    public static Period millis(int millis) {
199        return new Period(new int[] {0, 0, 0, 0, 0, 0, 0, millis}, PeriodType.standard());
200    }
201 
202    //-----------------------------------------------------------------------
203    /**
204     * Creates a period from two partially specified times, calculating
205     * by field difference.
206     * <p>
207     * The two partials must contain the same fields, thus you can specify
208     * two <code>LocalDate</code> objects, or two <code>LocalTime</code> objects,
209     * but not one of each. Also, the partial may not contain overlapping
210     * fields, such as dayOfWeek and dayOfMonth.
211     * <p>
212     * Calculation by field difference works by extracting the difference
213     * one field at a time and not wrapping into other fields.
214     * Thus 2005-06-09/2007-04-12 will yield P1Y-2M3D.
215     * <p>
216     * For example, you have an event that always runs from the 27th of
217     * each month to the 2nd of the next month. If you calculate this
218     * period using a standard constructor, then you will get between
219     * P3D and P6D depending on the month. If you use this method, then
220     * you will get P1M-25D. This field-difference based period can
221     * be successfully applied to each month of the year to obtain the
222     * correct end date for a given start date.
223     *
224     * @param start  the start of the period, must not be null
225     * @param end  the end of the period, must not be null
226     * @throws IllegalArgumentException if the partials are null or invalid
227     * @since 1.1
228     */
229    public static Period fieldDifference(ReadablePartial start, ReadablePartial end) {
230        if (start == null || end == null) {
231            throw new IllegalArgumentException("ReadablePartial objects must not be null");
232        }
233        if (start.size() != end.size()) {
234            throw new IllegalArgumentException("ReadablePartial objects must have the same set of fields");
235        }
236        DurationFieldType[] types = new DurationFieldType[start.size()];
237        int[] values = new int[start.size()];
238        for (int i = 0, isize = start.size(); i < isize; i++) {
239            if (start.getFieldType(i) != end.getFieldType(i)) {
240                throw new IllegalArgumentException("ReadablePartial objects must have the same set of fields");
241            }
242            types[i] = start.getFieldType(i).getDurationType();
243            if (i > 0 && types[i - 1] == types[i]) {
244                throw new IllegalArgumentException("ReadablePartial objects must not have overlapping fields");
245            }
246            values[i] = end.getValue(i) - start.getValue(i);
247        }
248        return new Period(values, PeriodType.forFields(types));
249    }
250 
251    //-----------------------------------------------------------------------
252    /**
253     * Creates a new empty period with the standard set of fields.
254     * <p>
255     * One way to initialise a period is as follows:
256     * <pre>
257     * Period = new Period().withYears(6).withMonths(3).withSeconds(23);
258     * </pre>
259     * Bear in mind that this creates four period instances in total, three of
260     * which are immediately discarded.
261     * The alterative is more efficient, but less readable:
262     * <pre>
263     * Period = new Period(6, 3, 0, 0, 0, 0, 23, 0);
264     * </pre>
265     * The following is also slightly less wasteful:
266     * <pre>
267     * Period = Period.years(6).withMonths(3).withSeconds(23);
268     * </pre>
269     */
270    public Period() {
271        super(0L, null, null);
272    }
273 
274    /**
275     * Create a period from a set of field values using the standard set of fields.
276     * Note that the parameters specify the time fields hours, minutes,
277     * seconds and millis, not the date fields.
278     *
279     * @param hours  amount of hours in this period
280     * @param minutes  amount of minutes in this period
281     * @param seconds  amount of seconds in this period
282     * @param millis  amount of milliseconds in this period
283     */
284    public Period(int hours, int minutes, int seconds, int millis) {
285        super(0, 0, 0, 0, hours, minutes, seconds, millis, PeriodType.standard());
286    }
287 
288    /**
289     * Create a period from a set of field values using the standard set of fields.
290     *
291     * @param years  amount of years in this period
292     * @param months  amount of months in this period
293     * @param weeks  amount of weeks in this period
294     * @param days  amount of days in this period
295     * @param hours  amount of hours in this period
296     * @param minutes  amount of minutes in this period
297     * @param seconds  amount of seconds in this period
298     * @param millis  amount of milliseconds in this period
299     */
300    public Period(int years, int months, int weeks, int days,
301                  int hours, int minutes, int seconds, int millis) {
302        super(years, months, weeks, days, hours, minutes, seconds, millis, PeriodType.standard());
303    }
304 
305    /**
306     * Create a period from a set of field values.
307     * <p>
308     * There is usually little need to use this constructor.
309     * The period type is used primarily to define how to split an interval into a period.
310     * As this constructor already is split, the period type does no real work.
311     *
312     * @param years  amount of years in this period, which must be zero if unsupported
313     * @param months  amount of months in this period, which must be zero if unsupported
314     * @param weeks  amount of weeks in this period, which must be zero if unsupported
315     * @param days  amount of days in this period, which must be zero if unsupported
316     * @param hours  amount of hours in this period, which must be zero if unsupported
317     * @param minutes  amount of minutes in this period, which must be zero if unsupported
318     * @param seconds  amount of seconds in this period, which must be zero if unsupported
319     * @param millis  amount of milliseconds in this period, which must be zero if unsupported
320     * @param type  which set of fields this period supports, null means AllType
321     * @throws IllegalArgumentException if an unsupported field's value is non-zero
322     */
323    public Period(int years, int months, int weeks, int days,
324                    int hours, int minutes, int seconds, int millis, PeriodType type) {
325        super(years, months, weeks, days, hours, minutes, seconds, millis, type);
326    }
327 
328    /**
329     * Creates a period from the given millisecond duration using the standard
330     * set of fields.
331     * <p>
332     * Only precise fields in the period type will be used.
333     * For the standard period type this is the time fields only.
334     * Thus the year, month, week and day fields will not be populated.
335     * <p>
336     * If the duration is small, less than one day, then this method will perform
337     * as you might expect and split the fields evenly.
338     * <p>
339     * If the duration is larger than one day then all the remaining duration will
340     * be stored in the largest available precise field, hours in this case.
341     * <p>
342     * For example, a duration equal to (365 + 60 + 5) days will be converted to
343     * ((365 + 60 + 5) * 24) hours by this constructor.
344     * <p>
345     * For more control over the conversion process, you have two options:
346     * <ul>
347     * <li>convert the duration to an {@link Interval}, and from there obtain the period
348     * <li>specify a period type that contains precise definitions of the day and larger
349     * fields, such as UTC
350     * </ul>
351     *
352     * @param duration  the duration, in milliseconds
353     */
354    public Period(long duration) {
355        super(duration, null, null);
356    }
357 
358    /**
359     * Creates a period from the given millisecond duration.
360     * <p>
361     * Only precise fields in the period type will be used.
362     * Imprecise fields will not be populated.
363     * <p>
364     * If the duration is small then this method will perform
365     * as you might expect and split the fields evenly.
366     * <p>
367     * If the duration is large then all the remaining duration will
368     * be stored in the largest available precise field.
369     * For details as to which fields are precise, review the period type javadoc.
370     *
371     * @param duration  the duration, in milliseconds
372     * @param type  which set of fields this period supports, null means standard
373     */
374    public Period(long duration, PeriodType type) {
375        super(duration, type, null);
376    }
377 
378    /**
379     * Creates a period from the given millisecond duration using the standard
380     * set of fields.
381     * <p>
382     * Only precise fields in the period type will be used.
383     * Imprecise fields will not be populated.
384     * <p>
385     * If the duration is small then this method will perform
386     * as you might expect and split the fields evenly.
387     * <p>
388     * If the duration is large then all the remaining duration will
389     * be stored in the largest available precise field.
390     * For details as to which fields are precise, review the period type javadoc.
391     *
392     * @param duration  the duration, in milliseconds
393     * @param chronology  the chronology to use to split the duration, null means ISO default
394     */
395    public Period(long duration, Chronology chronology) {
396        super(duration, null, chronology);
397    }
398 
399    /**
400     * Creates a period from the given millisecond duration.
401     * <p>
402     * Only precise fields in the period type will be used.
403     * Imprecise fields will not be populated.
404     * <p>
405     * If the duration is small then this method will perform
406     * as you might expect and split the fields evenly.
407     * <p>
408     * If the duration is large then all the remaining duration will
409     * be stored in the largest available precise field.
410     * For details as to which fields are precise, review the period type javadoc.
411     *
412     * @param duration  the duration, in milliseconds
413     * @param type  which set of fields this period supports, null means standard
414     * @param chronology  the chronology to use to split the duration, null means ISO default
415     */
416    public Period(long duration, PeriodType type, Chronology chronology) {
417        super(duration, type, chronology);
418    }
419 
420    /**
421     * Creates a period from the given interval endpoints using the standard
422     * set of fields.
423     *
424     * @param startInstant  interval start, in milliseconds
425     * @param endInstant  interval end, in milliseconds
426     */
427    public Period(long startInstant, long endInstant) {
428        super(startInstant, endInstant, null, null);
429    }
430 
431    /**
432     * Creates a period from the given interval endpoints.
433     *
434     * @param startInstant  interval start, in milliseconds
435     * @param endInstant  interval end, in milliseconds
436     * @param type  which set of fields this period supports, null means standard
437     */
438    public Period(long startInstant, long endInstant, PeriodType type) {
439        super(startInstant, endInstant, type, null);
440    }
441 
442    /**
443     * Creates a period from the given interval endpoints using the standard
444     * set of fields.
445     *
446     * @param startInstant  interval start, in milliseconds
447     * @param endInstant  interval end, in milliseconds
448     * @param chrono  the chronology to use, null means ISO in default zone
449     */
450    public Period(long startInstant, long endInstant, Chronology chrono) {
451        super(startInstant, endInstant, null, chrono);
452    }
453 
454    /**
455     * Creates a period from the given interval endpoints.
456     *
457     * @param startInstant  interval start, in milliseconds
458     * @param endInstant  interval end, in milliseconds
459     * @param type  which set of fields this period supports, null means standard
460     * @param chrono  the chronology to use, null means ISO in default zone
461     */
462    public Period(long startInstant, long endInstant, PeriodType type, Chronology chrono) {
463        super(startInstant, endInstant, type, chrono);
464    }
465 
466    /**
467     * Creates a period from the given interval endpoints using the standard
468     * set of fields.
469     *
470     * @param startInstant  interval start, null means now
471     * @param endInstant  interval end, null means now
472     */
473    public Period(ReadableInstant startInstant, ReadableInstant endInstant) {
474        super(startInstant, endInstant, null);
475    }
476 
477    /**
478     * Creates a period from the given interval endpoints.
479     *
480     * @param startInstant  interval start, null means now
481     * @param endInstant  interval end, null means now
482     * @param type  which set of fields this period supports, null means standard
483     */
484    public Period(ReadableInstant startInstant, ReadableInstant endInstant, PeriodType type) {
485        super(startInstant, endInstant, type);
486    }
487 
488    /**
489     * Creates a period from two partially specified times.
490     * <p>
491     * The two partials must contain the same fields, thus you can specify
492     * two <code>LocalDate</code> objects, or two <code>LocalTime</code> objects,
493     * but not one of each.
494     * As these are Partial objects, time zones have no effect on the result.
495     * <p>
496     * The two partials must also both be contiguous - see
497     * {@link DateTimeUtils#isContiguous(ReadablePartial)} for a definition.
498     * Both <code>LocalDate</code> and <code>LocalTime</code> are contiguous.
499     * <p>
500     * An alternative way of constructing a Period from two Partials
501     * is {@link #fieldDifference(ReadablePartial, ReadablePartial)}.
502     * That method handles all kinds of partials.
503     *
504     * @param start  the start of the period, must not be null
505     * @param end  the end of the period, must not be null
506     * @throws IllegalArgumentException if the partials are null or invalid
507     * @since 1.1
508     */
509    public Period(ReadablePartial start, ReadablePartial end) {
510        super(start, end, null);
511    }
512 
513    /**
514     * Creates a period from two partially specified times.
515     * <p>
516     * The two partials must contain the same fields, thus you can specify
517     * two <code>LocalDate</code> objects, or two <code>LocalTime</code> objects,
518     * but not one of each.
519     * As these are Partial objects, time zones have no effect on the result.
520     * <p>
521     * The two partials must also both be contiguous - see
522     * {@link DateTimeUtils#isContiguous(ReadablePartial)} for a definition.
523     * Both <code>LocalDate</code> and <code>LocalTime</code> are contiguous.
524     * <p>
525     * An alternative way of constructing a Period from two Partials
526     * is {@link #fieldDifference(ReadablePartial, ReadablePartial)}.
527     * That method handles all kinds of partials.
528     *
529     * @param start  the start of the period, must not be null
530     * @param end  the end of the period, must not be null
531     * @param type  which set of fields this period supports, null means standard
532     * @throws IllegalArgumentException if the partials are null or invalid
533     * @since 1.1
534     */
535    public Period(ReadablePartial start, ReadablePartial end, PeriodType type) {
536        super(start, end, type);
537    }
538 
539    /**
540     * Creates a period from the given start point and the duration.
541     *
542     * @param startInstant  the interval start, null means now
543     * @param duration  the duration of the interval, null means zero-length
544     */
545    public Period(ReadableInstant startInstant, ReadableDuration duration) {
546        super(startInstant, duration, null);
547    }
548 
549    /**
550     * Creates a period from the given start point and the duration.
551     *
552     * @param startInstant  the interval start, null means now
553     * @param duration  the duration of the interval, null means zero-length
554     * @param type  which set of fields this period supports, null means standard
555     */
556    public Period(ReadableInstant startInstant, ReadableDuration duration, PeriodType type) {
557        super(startInstant, duration, type);
558    }
559 
560    /**
561     * Creates a period from the given duration and end point.
562     *
563     * @param duration  the duration of the interval, null means zero-length
564     * @param endInstant  the interval end, null means now
565     */
566    public Period(ReadableDuration duration, ReadableInstant endInstant) {
567        super(duration, endInstant, null);
568    }
569 
570    /**
571     * Creates a period from the given duration and end point.
572     *
573     * @param duration  the duration of the interval, null means zero-length
574     * @param endInstant  the interval end, null means now
575     * @param type  which set of fields this period supports, null means standard
576     */
577    public Period(ReadableDuration duration, ReadableInstant endInstant, PeriodType type) {
578        super(duration, endInstant, type);
579    }
580 
581    /**
582     * Creates a period by converting or copying from another object.
583     * <p>
584     * The recognised object types are defined in
585     * {@link org.joda.time.convert.ConverterManager ConverterManager} and
586     * include ReadablePeriod, ReadableInterval and String.
587     * The String formats are described by {@link ISOPeriodFormat#standard()}.
588     *
589     * @param period  period to convert
590     * @throws IllegalArgumentException if period is invalid
591     * @throws UnsupportedOperationException if an unsupported field's value is non-zero
592     */
593    public Period(Object period) {
594        super(period, null, null);
595    }
596 
597    /**
598     * Creates a period by converting or copying from another object.
599     * <p>
600     * The recognised object types are defined in
601     * {@link org.joda.time.convert.ConverterManager ConverterManager} and
602     * include ReadablePeriod, ReadableInterval and String.
603     * The String formats are described by {@link ISOPeriodFormat#standard()}.
604     *
605     * @param period  period to convert
606     * @param type  which set of fields this period supports, null means use converter
607     * @throws IllegalArgumentException if period is invalid
608     * @throws UnsupportedOperationException if an unsupported field's value is non-zero
609     */
610    public Period(Object period, PeriodType type) {
611        super(period, type, null);
612    }
613 
614    /**
615     * Creates a period by converting or copying from another object.
616     * <p>
617     * The recognised object types are defined in
618     * {@link org.joda.time.convert.ConverterManager ConverterManager} and
619     * include ReadablePeriod, ReadableInterval and String.
620     * The String formats are described by {@link ISOPeriodFormat#standard()}.
621     *
622     * @param period  period to convert
623     * @param chrono  the chronology to use, null means ISO in default zone
624     * @throws IllegalArgumentException if period is invalid
625     * @throws UnsupportedOperationException if an unsupported field's value is non-zero
626     */
627    public Period(Object period, Chronology chrono) {
628        super(period, null, chrono);
629    }
630 
631    /**
632     * Creates a period by converting or copying from another object.
633     * <p>
634     * The recognised object types are defined in
635     * {@link org.joda.time.convert.ConverterManager ConverterManager} and
636     * include ReadablePeriod, ReadableInterval and String.
637     * The String formats are described by {@link ISOPeriodFormat#standard()}.
638     *
639     * @param period  period to convert
640     * @param type  which set of fields this period supports, null means use converter
641     * @param chrono  the chronology to use, null means ISO in default zone
642     * @throws IllegalArgumentException if period is invalid
643     * @throws UnsupportedOperationException if an unsupported field's value is non-zero
644     */
645    public Period(Object period, PeriodType type, Chronology chrono) {
646        super(period, type, chrono);
647    }
648 
649    /**
650     * Constructor used when we trust ourselves.
651     *
652     * @param values  the values to use, not null, not cloned
653     * @param type  which set of fields this period supports, not null
654     */
655    private Period(int[] values, PeriodType type) {
656        super(values, type);
657    }
658 
659    //-----------------------------------------------------------------------
660    /**
661     * Get this period as an immutable <code>Period</code> object
662     * by returning <code>this</code>.
663     * 
664     * @return <code>this</code>
665     */
666    public Period toPeriod() {
667        return this;
668    }
669 
670    //-----------------------------------------------------------------------
671    /**
672     * Gets the years field part of the period.
673     * 
674     * @return the number of years in the period, zero if unsupported
675     */
676    public int getYears() {
677        return getPeriodType().getIndexedField(this, PeriodType.YEAR_INDEX);
678    }
679 
680    /**
681     * Gets the months field part of the period.
682     * 
683     * @return the number of months in the period, zero if unsupported
684     */
685    public int getMonths() {
686        return getPeriodType().getIndexedField(this, PeriodType.MONTH_INDEX);
687    }
688 
689    /**
690     * Gets the weeks field part of the period.
691     * 
692     * @return the number of weeks in the period, zero if unsupported
693     */
694    public int getWeeks() {
695        return getPeriodType().getIndexedField(this, PeriodType.WEEK_INDEX);
696    }
697 
698    /**
699     * Gets the days field part of the period.
700     * 
701     * @return the number of days in the period, zero if unsupported
702     */
703    public int getDays() {
704        return getPeriodType().getIndexedField(this, PeriodType.DAY_INDEX);
705    }
706 
707    //-----------------------------------------------------------------------
708    /**
709     * Gets the hours field part of the period.
710     * 
711     * @return the number of hours in the period, zero if unsupported
712     */
713    public int getHours() {
714        return getPeriodType().getIndexedField(this, PeriodType.HOUR_INDEX);
715    }
716 
717    /**
718     * Gets the minutes field part of the period.
719     * 
720     * @return the number of minutes in the period, zero if unsupported
721     */
722    public int getMinutes() {
723        return getPeriodType().getIndexedField(this, PeriodType.MINUTE_INDEX);
724    }
725 
726    /**
727     * Gets the seconds field part of the period.
728     * 
729     * @return the number of seconds in the period, zero if unsupported
730     */
731    public int getSeconds() {
732        return getPeriodType().getIndexedField(this, PeriodType.SECOND_INDEX);
733    }
734 
735    /**
736     * Gets the millis field part of the period.
737     * 
738     * @return the number of millis in the period, zero if unsupported
739     */
740    public int getMillis() {
741        return getPeriodType().getIndexedField(this, PeriodType.MILLI_INDEX);
742    }
743 
744    //-----------------------------------------------------------------------
745    /**
746     * Creates a new Period instance with the same field values but
747     * different PeriodType.
748     * <p>
749     * This period instance is immutable and unaffected by this method call.
750     * 
751     * @param type  the period type to use, null means standard
752     * @return the new period instance
753     * @throws IllegalArgumentException if the new period won't accept all of the current fields
754     */
755    public Period withPeriodType(PeriodType type) {
756        type = DateTimeUtils.getPeriodType(type);
757        if (type.equals(getPeriodType())) {
758            return this;
759        }
760        return new Period(this, type);
761    }
762 
763    /**
764     * Creates a new Period instance with the fields from the specified period
765     * copied on top of those from this period.
766     * <p>
767     * This period instance is immutable and unaffected by this method call.
768     * 
769     * @param period  the period to copy from, null ignored
770     * @return the new period instance
771     * @throws IllegalArgumentException if a field type is unsupported
772     */
773    public Period withFields(ReadablePeriod period) {
774        if (period == null) {
775            return this;
776        }
777        int[] newValues = getValues();  // cloned
778        newValues = super.mergePeriodInto(newValues, period);
779        return new Period(newValues, getPeriodType());
780    }
781 
782    //-----------------------------------------------------------------------
783    /**
784     * Creates a new Period instance with the specified field set to a new value.
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 set to
790     * @return the new period instance
791     * @throws IllegalArgumentException if the field type is null or unsupported
792     */
793    public Period withField(DurationFieldType field, int value) {
794        if (field == null) {
795            throw new IllegalArgumentException("Field must not be null");
796        }
797        int[] newValues = getValues();  // cloned
798        super.setFieldInto(newValues, field, value);
799        return new Period(newValues, getPeriodType());
800    }
801 
802    /**
803     * Creates a new Period instance with the valueToAdd added to the specified field.
804     * <p>
805     * This period instance is immutable and unaffected by this method call.
806     * 
807     * @param field  the field to set, not null
808     * @param value  the value to add
809     * @return the new period instance
810     * @throws IllegalArgumentException if the field type is null or unsupported
811     */
812    public Period withFieldAdded(DurationFieldType field, int value) {
813        if (field == null) {
814            throw new IllegalArgumentException("Field must not be null");
815        }
816        if (value == 0) {
817            return this;
818        }
819        int[] newValues = getValues();  // cloned
820        super.addFieldInto(newValues, field, value);
821        return new Period(newValues, getPeriodType());
822    }
823 
824    //-----------------------------------------------------------------------
825    /**
826     * Returns a new period with the specified number of years.
827     * <p>
828     * This period instance is immutable and unaffected by this method call.
829     *
830     * @param years  the amount of years to add, may be negative
831     * @return the new period with the increased years
832     * @throws UnsupportedOperationException if the field is not supported
833     */
834    public Period withYears(int years) {
835        int[] values = getValues();  // cloned
836        getPeriodType().setIndexedField(this, PeriodType.YEAR_INDEX, values, years);
837        return new Period(values, getPeriodType());
838    }
839 
840    /**
841     * Returns a new period with the specified number of months.
842     * <p>
843     * This period instance is immutable and unaffected by this method call.
844     *
845     * @param months  the amount of months to add, may be negative
846     * @return the new period with the increased months
847     * @throws UnsupportedOperationException if the field is not supported
848     */
849    public Period withMonths(int months) {
850        int[] values = getValues();  // cloned
851        getPeriodType().setIndexedField(this, PeriodType.MONTH_INDEX, values, months);
852        return new Period(values, getPeriodType());
853    }
854 
855    /**
856     * Returns a new period with the specified number of weeks.
857     * <p>
858     * This period instance is immutable and unaffected by this method call.
859     *
860     * @param weeks  the amount of weeks to add, may be negative
861     * @return the new period with the increased weeks
862     * @throws UnsupportedOperationException if the field is not supported
863     */
864    public Period withWeeks(int weeks) {
865        int[] values = getValues();  // cloned
866        getPeriodType().setIndexedField(this, PeriodType.WEEK_INDEX, values, weeks);
867        return new Period(values, getPeriodType());
868    }
869 
870    /**
871     * Returns a new period with the specified number of days.
872     * <p>
873     * This period instance is immutable and unaffected by this method call.
874     *
875     * @param days  the amount of days to add, may be negative
876     * @return the new period with the increased days
877     * @throws UnsupportedOperationException if the field is not supported
878     */
879    public Period withDays(int days) {
880        int[] values = getValues();  // cloned
881        getPeriodType().setIndexedField(this, PeriodType.DAY_INDEX, values, days);
882        return new Period(values, getPeriodType());
883    }
884 
885    /**
886     * Returns a new period with the specified number of hours.
887     * <p>
888     * This period instance is immutable and unaffected by this method call.
889     *
890     * @param hours  the amount of hours to add, may be negative
891     * @return the new period with the increased hours
892     * @throws UnsupportedOperationException if the field is not supported
893     */
894    public Period withHours(int hours) {
895        int[] values = getValues();  // cloned
896        getPeriodType().setIndexedField(this, PeriodType.HOUR_INDEX, values, hours);
897        return new Period(values, getPeriodType());
898    }
899 
900    /**
901     * Returns a new period with the specified number of minutes.
902     * <p>
903     * This period instance is immutable and unaffected by this method call.
904     *
905     * @param minutes  the amount of minutes to add, may be negative
906     * @return the new period with the increased minutes
907     * @throws UnsupportedOperationException if the field is not supported
908     */
909    public Period withMinutes(int minutes) {
910        int[] values = getValues();  // cloned
911        getPeriodType().setIndexedField(this, PeriodType.MINUTE_INDEX, values, minutes);
912        return new Period(values, getPeriodType());
913    }
914 
915    /**
916     * Returns a new period with the specified number of seconds.
917     * <p>
918     * This period instance is immutable and unaffected by this method call.
919     *
920     * @param seconds  the amount of seconds to add, may be negative
921     * @return the new period with the increased seconds
922     * @throws UnsupportedOperationException if the field is not supported
923     */
924    public Period withSeconds(int seconds) {
925        int[] values = getValues();  // cloned
926        getPeriodType().setIndexedField(this, PeriodType.SECOND_INDEX, values, seconds);
927        return new Period(values, getPeriodType());
928    }
929 
930    /**
931     * Returns a new period with the specified number of millis.
932     * <p>
933     * This period instance is immutable and unaffected by this method call.
934     *
935     * @param millis  the amount of millis to add, may be negative
936     * @return the new period with the increased millis
937     * @throws UnsupportedOperationException if the field is not supported
938     */
939    public Period withMillis(int millis) {
940        int[] values = getValues();  // cloned
941        getPeriodType().setIndexedField(this, PeriodType.MILLI_INDEX, values, millis);
942        return new Period(values, getPeriodType());
943    }
944 
945    //-----------------------------------------------------------------------
946    /**
947     * Returns a new period with the specified period added.
948     * <p>
949     * Each field of the period is added separately. Thus a period of
950     * 2 hours 30 minutes plus 3 hours 40 minutes will produce a result
951     * of 5 hours 70 minutes - see {@link #normalizedStandard()}.
952     * <p>
953     * If the period being added contains a non-zero amount for a field that
954     * is not supported in this period then an exception is thrown.
955     * <p>
956     * This period instance is immutable and unaffected by this method call.
957     *
958     * @param period  the period to add, null adds zero and returns this
959     * @return the new updated period
960     * @throws UnsupportedOperationException if any field is not supported
961     * @since 1.5
962     */
963    public Period plus(ReadablePeriod period) {
964        if (period == null) {
965            return this;
966        }
967        int[] values = getValues();  // cloned
968        getPeriodType().addIndexedField(this, PeriodType.YEAR_INDEX, values, period.get(DurationFieldType.YEARS_TYPE));
969        getPeriodType().addIndexedField(this, PeriodType.MONTH_INDEX, values, period.get(DurationFieldType.MONTHS_TYPE));
970        getPeriodType().addIndexedField(this, PeriodType.WEEK_INDEX, values, period.get(DurationFieldType.WEEKS_TYPE));
971        getPeriodType().addIndexedField(this, PeriodType.DAY_INDEX, values, period.get(DurationFieldType.DAYS_TYPE));
972        getPeriodType().addIndexedField(this, PeriodType.HOUR_INDEX, values, period.get(DurationFieldType.HOURS_TYPE));
973        getPeriodType().addIndexedField(this, PeriodType.MINUTE_INDEX, values, period.get(DurationFieldType.MINUTES_TYPE));
974        getPeriodType().addIndexedField(this, PeriodType.SECOND_INDEX, values, period.get(DurationFieldType.SECONDS_TYPE));
975        getPeriodType().addIndexedField(this, PeriodType.MILLI_INDEX, values, period.get(DurationFieldType.MILLIS_TYPE));
976        return new Period(values, getPeriodType());
977    }
978 
979    //-----------------------------------------------------------------------
980    /**
981     * Returns a new period with the specified number of years added.
982     * <p>
983     * This period instance is immutable and unaffected by this method call.
984     *
985     * @param years  the amount of years to add, may be negative
986     * @return the new period with the increased years
987     * @throws UnsupportedOperationException if the field is not supported
988     */
989    public Period plusYears(int years) {
990        if (years == 0) {
991            return this;
992        }
993        int[] values = getValues();  // cloned
994        getPeriodType().addIndexedField(this, PeriodType.YEAR_INDEX, values, years);
995        return new Period(values, getPeriodType());
996    }
997 
998    /**
999     * Returns a new period plus the specified number of months added.
1000     * <p>
1001     * This period instance is immutable and unaffected by this method call.
1002     *
1003     * @param months  the amount of months to add, may be negative
1004     * @return the new period plus the increased months
1005     * @throws UnsupportedOperationException if the field is not supported
1006     */
1007    public Period plusMonths(int months) {
1008        if (months == 0) {
1009            return this;
1010        }
1011        int[] values = getValues();  // cloned
1012        getPeriodType().addIndexedField(this, PeriodType.MONTH_INDEX, values, months);
1013        return new Period(values, getPeriodType());
1014    }
1015 
1016    /**
1017     * Returns a new period plus the specified number of weeks added.
1018     * <p>
1019     * This period instance is immutable and unaffected by this method call.
1020     *
1021     * @param weeks  the amount of weeks to add, may be negative
1022     * @return the new period plus the increased weeks
1023     * @throws UnsupportedOperationException if the field is not supported
1024     */
1025    public Period plusWeeks(int weeks) {
1026        if (weeks == 0) {
1027            return this;
1028        }
1029        int[] values = getValues();  // cloned
1030        getPeriodType().addIndexedField(this, PeriodType.WEEK_INDEX, values, weeks);
1031        return new Period(values, getPeriodType());
1032    }
1033 
1034    /**
1035     * Returns a new period plus the specified number of days added.
1036     * <p>
1037     * This period instance is immutable and unaffected by this method call.
1038     *
1039     * @param days  the amount of days to add, may be negative
1040     * @return the new period plus the increased days
1041     * @throws UnsupportedOperationException if the field is not supported
1042     */
1043    public Period plusDays(int days) {
1044        if (days == 0) {
1045            return this;
1046        }
1047        int[] values = getValues();  // cloned
1048        getPeriodType().addIndexedField(this, PeriodType.DAY_INDEX, values, days);
1049        return new Period(values, getPeriodType());
1050    }
1051 
1052    /**
1053     * Returns a new period plus the specified number of hours added.
1054     * <p>
1055     * This period instance is immutable and unaffected by this method call.
1056     *
1057     * @param hours  the amount of hours to add, may be negative
1058     * @return the new period plus the increased hours
1059     * @throws UnsupportedOperationException if the field is not supported
1060     */
1061    public Period plusHours(int hours) {
1062        if (hours == 0) {
1063            return this;
1064        }
1065        int[] values = getValues();  // cloned
1066        getPeriodType().addIndexedField(this, PeriodType.HOUR_INDEX, values, hours);
1067        return new Period(values, getPeriodType());
1068    }
1069 
1070    /**
1071     * Returns a new period plus the specified number of minutes added.
1072     * <p>
1073     * This period instance is immutable and unaffected by this method call.
1074     *
1075     * @param minutes  the amount of minutes to add, may be negative
1076     * @return the new period plus the increased minutes
1077     * @throws UnsupportedOperationException if the field is not supported
1078     */
1079    public Period plusMinutes(int minutes) {
1080        if (minutes == 0) {
1081            return this;
1082        }
1083        int[] values = getValues();  // cloned
1084        getPeriodType().addIndexedField(this, PeriodType.MINUTE_INDEX, values, minutes);
1085        return new Period(values, getPeriodType());
1086    }
1087 
1088    /**
1089     * Returns a new period plus the specified number of seconds added.
1090     * <p>
1091     * This period instance is immutable and unaffected by this method call.
1092     *
1093     * @param seconds  the amount of seconds to add, may be negative
1094     * @return the new period plus the increased seconds
1095     * @throws UnsupportedOperationException if the field is not supported
1096     */
1097    public Period plusSeconds(int seconds) {
1098        if (seconds == 0) {
1099            return this;
1100        }
1101        int[] values = getValues();  // cloned
1102        getPeriodType().addIndexedField(this, PeriodType.SECOND_INDEX, values, seconds);
1103        return new Period(values, getPeriodType());
1104    }
1105 
1106    /**
1107     * Returns a new period plus the specified number of millis added.
1108     * <p>
1109     * This period instance is immutable and unaffected by this method call.
1110     *
1111     * @param millis  the amount of millis to add, may be negative
1112     * @return the new period plus the increased millis
1113     * @throws UnsupportedOperationException if the field is not supported
1114     */
1115    public Period plusMillis(int millis) {
1116        if (millis == 0) {
1117            return this;
1118        }
1119        int[] values = getValues();  // cloned
1120        getPeriodType().addIndexedField(this, PeriodType.MILLI_INDEX, values, millis);
1121        return new Period(values, getPeriodType());
1122    }
1123 
1124    //-----------------------------------------------------------------------
1125    /**
1126     * Returns a new period with the specified period subtracted.
1127     * <p>
1128     * Each field of the period is subtracted separately. Thus a period of
1129     * 3 hours 30 minutes minus 2 hours 40 minutes will produce a result
1130     * of 1 hour and -10 minutes - see {@link #normalizedStandard()}.
1131     * <p>
1132     * If the period being added contains a non-zero amount for a field that
1133     * is not supported in this period then an exception is thrown.
1134     * <p>
1135     * This period instance is immutable and unaffected by this method call.
1136     *
1137     * @param period  the period to add, null adds zero and returns this
1138     * @return the new updated period
1139     * @throws UnsupportedOperationException if any field is not supported
1140     * @since 1.5
1141     */
1142    public Period minus(ReadablePeriod period) {
1143        if (period == null) {
1144            return this;
1145        }
1146        int[] values = getValues();  // cloned
1147        getPeriodType().addIndexedField(this, PeriodType.YEAR_INDEX, values, -period.get(DurationFieldType.YEARS_TYPE));
1148        getPeriodType().addIndexedField(this, PeriodType.MONTH_INDEX, values, -period.get(DurationFieldType.MONTHS_TYPE));
1149        getPeriodType().addIndexedField(this, PeriodType.WEEK_INDEX, values, -period.get(DurationFieldType.WEEKS_TYPE));
1150        getPeriodType().addIndexedField(this, PeriodType.DAY_INDEX, values, -period.get(DurationFieldType.DAYS_TYPE));
1151        getPeriodType().addIndexedField(this, PeriodType.HOUR_INDEX, values, -period.get(DurationFieldType.HOURS_TYPE));
1152        getPeriodType().addIndexedField(this, PeriodType.MINUTE_INDEX, values, -period.get(DurationFieldType.MINUTES_TYPE));
1153        getPeriodType().addIndexedField(this, PeriodType.SECOND_INDEX, values, -period.get(DurationFieldType.SECONDS_TYPE));
1154        getPeriodType().addIndexedField(this, PeriodType.MILLI_INDEX, values, -period.get(DurationFieldType.MILLIS_TYPE));
1155        return new Period(values, getPeriodType());
1156    }
1157 
1158    //-----------------------------------------------------------------------
1159    /**
1160     * Returns a new period with the specified number of years taken away.
1161     * <p>
1162     * This period instance is immutable and unaffected by this method call.
1163     *
1164     * @param years  the amount of years to take away, may be negative
1165     * @return the new period with the increased years
1166     * @throws UnsupportedOperationException if the field is not supported
1167     */
1168    public Period minusYears(int years) {
1169        return plusYears(-years);
1170    }
1171 
1172    /**
1173     * Returns a new period minus the specified number of months taken away.
1174     * <p>
1175     * This period instance is immutable and unaffected by this method call.
1176     *
1177     * @param months  the amount of months to take away, may be negative
1178     * @return the new period minus the increased months
1179     * @throws UnsupportedOperationException if the field is not supported
1180     */
1181    public Period minusMonths(int months) {
1182        return plusMonths(-months);
1183    }
1184 
1185    /**
1186     * Returns a new period minus the specified number of weeks taken away.
1187     * <p>
1188     * This period instance is immutable and unaffected by this method call.
1189     *
1190     * @param weeks  the amount of weeks to take away, may be negative
1191     * @return the new period minus the increased weeks
1192     * @throws UnsupportedOperationException if the field is not supported
1193     */
1194    public Period minusWeeks(int weeks) {
1195        return plusWeeks(-weeks);
1196    }
1197 
1198    /**
1199     * Returns a new period minus the specified number of days taken away.
1200     * <p>
1201     * This period instance is immutable and unaffected by this method call.
1202     *
1203     * @param days  the amount of days to take away, may be negative
1204     * @return the new period minus the increased days
1205     * @throws UnsupportedOperationException if the field is not supported
1206     */
1207    public Period minusDays(int days) {
1208        return plusDays(-days);
1209    }
1210 
1211    /**
1212     * Returns a new period minus the specified number of hours taken away.
1213     * <p>
1214     * This period instance is immutable and unaffected by this method call.
1215     *
1216     * @param hours  the amount of hours to take away, may be negative
1217     * @return the new period minus the increased hours
1218     * @throws UnsupportedOperationException if the field is not supported
1219     */
1220    public Period minusHours(int hours) {
1221        return plusHours(-hours);
1222    }
1223 
1224    /**
1225     * Returns a new period minus the specified number of minutes taken away.
1226     * <p>
1227     * This period instance is immutable and unaffected by this method call.
1228     *
1229     * @param minutes  the amount of minutes to take away, may be negative
1230     * @return the new period minus the increased minutes
1231     * @throws UnsupportedOperationException if the field is not supported
1232     */
1233    public Period minusMinutes(int minutes) {
1234        return plusMinutes(-minutes);
1235    }
1236 
1237    /**
1238     * Returns a new period minus the specified number of seconds taken away.
1239     * <p>
1240     * This period instance is immutable and unaffected by this method call.
1241     *
1242     * @param seconds  the amount of seconds to take away, may be negative
1243     * @return the new period minus the increased seconds
1244     * @throws UnsupportedOperationException if the field is not supported
1245     */
1246    public Period minusSeconds(int seconds) {
1247        return plusSeconds(-seconds);
1248    }
1249 
1250    /**
1251     * Returns a new period minus the specified number of millis taken away.
1252     * <p>
1253     * This period instance is immutable and unaffected by this method call.
1254     *
1255     * @param millis  the amount of millis to take away, may be negative
1256     * @return the new period minus the increased millis
1257     * @throws UnsupportedOperationException if the field is not supported
1258     */
1259    public Period minusMillis(int millis) {
1260        return plusMillis(-millis);
1261    }
1262 
1263    //-----------------------------------------------------------------------
1264    /**
1265     * Converts this period to a period in weeks assuming a
1266     * 7 day week, 24 hour day, 60 minute hour and 60 second minute.
1267     * <p>
1268     * This method allows you to convert between different types of period.
1269     * However to achieve this it makes the assumption that all
1270     * weeks are 7 days, all days are 24 hours, all hours are 60 minutes and
1271     * all minutes are 60 seconds. This is not true when daylight savings time
1272     * is considered, and may also not be true for some unusual chronologies.
1273     * However, it is included as it is a useful operation for many
1274     * applications and business rules.
1275     * <p>
1276     * If the period contains years or months, an exception will be thrown.
1277     * 
1278     * @return a period representing the number of standard weeks in this period
1279     * @throws UnsupportedOperationException if the period contains years or months
1280     * @throws ArithmeticException if the number of weeks is too large to be represented
1281     * @since 1.5
1282     */
1283    public Weeks toStandardWeeks() {
1284        checkYearsAndMonths("Weeks");
1285        long millis = getMillis();  // assign to a long
1286        millis += ((long) getSeconds()) * DateTimeConstants.MILLIS_PER_SECOND;
1287        millis += ((long) getMinutes()) * DateTimeConstants.MILLIS_PER_MINUTE;
1288        millis += ((long) getHours()) * DateTimeConstants.MILLIS_PER_HOUR;
1289        millis += ((long) getDays()) * DateTimeConstants.MILLIS_PER_DAY;
1290        long weeks = ((long) getWeeks()) + millis / DateTimeConstants.MILLIS_PER_WEEK;
1291        return Weeks.weeks(FieldUtils.safeToInt(weeks));
1292    }
1293 
1294    /**
1295     * Converts this period to a period in days assuming a
1296     * 7 day week, 24 hour day, 60 minute hour and 60 second minute.
1297     * <p>
1298     * This method allows you to convert between different types of period.
1299     * However to achieve this it makes the assumption that all
1300     * weeks are 7 days, all days are 24 hours, all hours are 60 minutes and
1301     * all minutes are 60 seconds. This is not true when daylight savings time
1302     * is considered, and may also not be true for some unusual chronologies.
1303     * However, it is included as it is a useful operation for many
1304     * applications and business rules.
1305     * <p>
1306     * If the period contains years or months, an exception will be thrown.
1307     * 
1308     * @return a period representing the number of standard days in this period
1309     * @throws UnsupportedOperationException if the period contains years or months
1310     * @throws ArithmeticException if the number of days is too large to be represented
1311     * @since 1.5
1312     */
1313    public Days toStandardDays() {
1314        checkYearsAndMonths("Days");
1315        long millis = getMillis();  // assign to a long
1316        millis += ((long) getSeconds()) * DateTimeConstants.MILLIS_PER_SECOND;
1317        millis += ((long) getMinutes()) * DateTimeConstants.MILLIS_PER_MINUTE;
1318        millis += ((long) getHours()) * DateTimeConstants.MILLIS_PER_HOUR;
1319        long days = millis / DateTimeConstants.MILLIS_PER_DAY;
1320        days = FieldUtils.safeAdd(days, getDays());
1321        days = FieldUtils.safeAdd(days, ((long) getWeeks()) * ((long) DateTimeConstants.DAYS_PER_WEEK));
1322        return Days.days(FieldUtils.safeToInt(days));
1323    }
1324 
1325    /**
1326     * Converts this period to a period in hours assuming a
1327     * 7 day week, 24 hour day, 60 minute hour and 60 second minute.
1328     * <p>
1329     * This method allows you to convert between different types of period.
1330     * However to achieve this it makes the assumption that all
1331     * weeks are 7 days, all days are 24 hours, all hours are 60 minutes and
1332     * all minutes are 60 seconds. This is not true when daylight savings time
1333     * is considered, and may also not be true for some unusual chronologies.
1334     * However, it is included as it is a useful operation for many
1335     * applications and business rules.
1336     * <p>
1337     * If the period contains years or months, an exception will be thrown.
1338     * 
1339     * @return a period representing the number of standard hours in this period
1340     * @throws UnsupportedOperationException if the period contains years or months
1341     * @throws ArithmeticException if the number of hours is too large to be represented
1342     * @since 1.5
1343     */
1344    public Hours toStandardHours() {
1345        checkYearsAndMonths("Hours");
1346        long millis = getMillis();  // assign to a long
1347        millis += ((long) getSeconds()) * DateTimeConstants.MILLIS_PER_SECOND;
1348        millis += ((long) getMinutes()) * DateTimeConstants.MILLIS_PER_MINUTE;
1349        long hours = millis / DateTimeConstants.MILLIS_PER_HOUR;
1350        hours = FieldUtils.safeAdd(hours, getHours());
1351        hours = FieldUtils.safeAdd(hours, ((long) getDays()) * ((long) DateTimeConstants.HOURS_PER_DAY));
1352        hours = FieldUtils.safeAdd(hours, ((long) getWeeks()) * ((long) DateTimeConstants.HOURS_PER_WEEK));
1353        return Hours.hours(FieldUtils.safeToInt(hours));
1354    }
1355 
1356    /**
1357     * Converts this period to a period in minutes assuming a
1358     * 7 day week, 24 hour day, 60 minute hour and 60 second minute.
1359     * <p>
1360     * This method allows you to convert between different types of period.
1361     * However to achieve this it makes the assumption that all
1362     * weeks are 7 days, all days are 24 hours, all hours are 60 minutes and
1363     * all minutes are 60 seconds. This is not true when daylight savings time
1364     * is considered, and may also not be true for some unusual chronologies.
1365     * However, it is included as it is a useful operation for many
1366     * applications and business rules.
1367     * <p>
1368     * If the period contains years or months, an exception will be thrown.
1369     * 
1370     * @return a period representing the number of standard minutes in this period
1371     * @throws UnsupportedOperationException if the period contains years or months
1372     * @throws ArithmeticException if the number of minutes is too large to be represented
1373     * @since 1.5
1374     */
1375    public Minutes toStandardMinutes() {
1376        checkYearsAndMonths("Minutes");
1377        long millis = getMillis();  // assign to a long
1378        millis += ((long) getSeconds()) * DateTimeConstants.MILLIS_PER_SECOND;
1379        long minutes = millis / DateTimeConstants.MILLIS_PER_MINUTE;
1380        minutes = FieldUtils.safeAdd(minutes, getMinutes());
1381        minutes = FieldUtils.safeAdd(minutes, ((long) getHours()) * ((long) DateTimeConstants.MINUTES_PER_HOUR));
1382        minutes = FieldUtils.safeAdd(minutes, ((long) getDays()) * ((long) DateTimeConstants.MINUTES_PER_DAY));
1383        minutes = FieldUtils.safeAdd(minutes, ((long) getWeeks()) * ((long) DateTimeConstants.MINUTES_PER_WEEK));
1384        return Minutes.minutes(FieldUtils.safeToInt(minutes));
1385    }
1386 
1387    /**
1388     * Converts this period to a period in seconds assuming a
1389     * 7 day week, 24 hour day, 60 minute hour and 60 second minute.
1390     * <p>
1391     * This method allows you to convert between different types of period.
1392     * However to achieve this it makes the assumption that all
1393     * weeks are 7 days, all days are 24 hours, all hours are 60 minutes and
1394     * all minutes are 60 seconds. This is not true when daylight savings time
1395     * is considered, and may also not be true for some unusual chronologies.
1396     * However, it is included as it is a useful operation for many
1397     * applications and business rules.
1398     * <p>
1399     * If the period contains years or months, an exception will be thrown.
1400     * 
1401     * @return a period representing the number of standard seconds in this period
1402     * @throws UnsupportedOperationException if the period contains years or months
1403     * @throws ArithmeticException if the number of seconds is too large to be represented
1404     * @since 1.5
1405     */
1406    public Seconds toStandardSeconds() {
1407        checkYearsAndMonths("Seconds");
1408        long seconds = getMillis() / DateTimeConstants.MILLIS_PER_SECOND;
1409        seconds = FieldUtils.safeAdd(seconds, getSeconds());
1410        seconds = FieldUtils.safeAdd(seconds, ((long) getMinutes()) * ((long) DateTimeConstants.SECONDS_PER_MINUTE));
1411        seconds = FieldUtils.safeAdd(seconds, ((long) getHours()) * ((long) DateTimeConstants.SECONDS_PER_HOUR));
1412        seconds = FieldUtils.safeAdd(seconds, ((long) getDays()) * ((long) DateTimeConstants.SECONDS_PER_DAY));
1413        seconds = FieldUtils.safeAdd(seconds, ((long) getWeeks()) * ((long) DateTimeConstants.SECONDS_PER_WEEK));
1414        return Seconds.seconds(FieldUtils.safeToInt(seconds));
1415    }
1416 
1417    //-----------------------------------------------------------------------
1418    /**
1419     * Converts this period to a duration assuming a
1420     * 7 day week, 24 hour day, 60 minute hour and 60 second minute.
1421     * <p>
1422     * This method allows you to convert from a period to a duration.
1423     * However to achieve this it makes the assumption that all
1424     * weeks are 7 days, all days are 24 hours, all hours are 60 minutes and
1425     * all minutes are 60 seconds. This is not true when daylight savings time
1426     * is considered, and may also not be true for some unusual chronologies.
1427     * However, it is included as it is a useful operation for many
1428     * applications and business rules.
1429     * <p>
1430     * If the period contains years or months, an exception will be thrown.
1431     * 
1432     * @return a duration equivalent to this period
1433     * @throws UnsupportedOperationException if the period contains years or months
1434     * @since 1.5
1435     */
1436    public Duration toStandardDuration() {
1437        checkYearsAndMonths("Duration");
1438        long millis = getMillis();  // no overflow can happen, even with Integer.MAX_VALUEs
1439        millis += (((long) getSeconds()) * ((long) DateTimeConstants.MILLIS_PER_SECOND));
1440        millis += (((long) getMinutes()) * ((long) DateTimeConstants.MILLIS_PER_MINUTE));
1441        millis += (((long) getHours()) * ((long) DateTimeConstants.MILLIS_PER_HOUR));
1442        millis += (((long) getDays()) * ((long) DateTimeConstants.MILLIS_PER_DAY));
1443        millis += (((long) getWeeks()) * ((long) DateTimeConstants.MILLIS_PER_WEEK));
1444        return new Duration(millis);
1445    }
1446 
1447    /**
1448     * Check that there are no years or months in the period.
1449     * 
1450     * @param destintionType  the destination type, not null
1451     * @throws UnsupportedOperationException if the period contains years or months
1452     */
1453    private void checkYearsAndMonths(String destintionType) {
1454        if (getMonths() != 0) {
1455            throw new UnsupportedOperationException("Cannot convert to " + destintionType + " as this period contains months and months vary in length");
1456        }
1457        if (getYears() != 0) {
1458            throw new UnsupportedOperationException("Cannot convert to " + destintionType + " as this period contains years and years vary in length");
1459        }
1460    }
1461 
1462    //-----------------------------------------------------------------------
1463    /**
1464     * Normalizes this period using standard rules, assuming a 12 month year,
1465     * 7 day week, 24 hour day, 60 minute hour and 60 second minute.
1466     * <p>
1467     * This method allows you to normalize a period.
1468     * However to achieve this it makes the assumption that all years are
1469     * 12 months, all weeks are 7 days, all days are 24 hours,
1470     * all hours are 60 minutes and all minutes are 60 seconds. This is not
1471     * true when daylight savings time is considered, and may also not be true
1472     * for some chronologies. However, it is included as it is a useful operation
1473     * for many applications and business rules.
1474     * <p>
1475     * If the period contains years or months, then the months will be
1476     * normalized to be between 0 and 11. The days field and below will be
1477     * normalized as necessary, however this will not overflow into the months
1478     * field. Thus a period of 1 year 15 months will normalize to 2 years 3 months.
1479     * But a period of 1 month 40 days will remain as 1 month 40 days.
1480     * <p>
1481     * The result will always have a <code>PeriodType</code> of standard, thus
1482     * days will be grouped into weeks.
1483     * 
1484     * @return a normalized period equivalent to this period
1485     * @throws ArithmeticException if any field is too large to be represented
1486     * @since 1.5
1487     */
1488    public Period normalizedStandard() {
1489        return normalizedStandard(PeriodType.standard());
1490    }
1491 
1492    //-----------------------------------------------------------------------
1493    /**
1494     * Normalizes this period using standard rules, assuming a 12 month year,
1495     * 7 day week, 24 hour day, 60 minute hour and 60 second minute,
1496     * providing control over how the result is split into fields.
1497     * <p>
1498     * This method allows you to normalize a period.
1499     * However to achieve this it makes the assumption that all years are
1500     * 12 months, all weeks are 7 days, all days are 24 hours,
1501     * all hours are 60 minutes and all minutes are 60 seconds. This is not
1502     * true when daylight savings time is considered, and may also not be true
1503     * for some chronologies. However, it is included as it is a useful operation
1504     * for many applications and business rules.
1505     * <p>
1506     * If the period contains years or months, then the months will be
1507     * normalized to be between 0 and 11. The days field and below will be
1508     * normalized as necessary, however this will not overflow into the months
1509     * field. Thus a period of 1 year 15 months will normalize to 2 years 3 months.
1510     * But a period of 1 month 40 days will remain as 1 month 40 days.
1511     * <p>
1512     * The PeriodType parameter controls how the result is created. It allows
1513     * you to omit certain fields from the result if desired. For example,
1514     * you may not want the result to include weeks, in which case you pass
1515     * in <code>PeriodType.yearMonthDayTime()</code>.
1516     * 
1517     * @param type  the period type of the new period, null means standard type
1518     * @return a normalized period equivalent to this period
1519     * @throws ArithmeticException if any field is too large to be represented
1520     * @throws UnsupportedOperationException if this period contains non-zero
1521     *  years or months but the specified period type does not support them
1522     * @since 1.5
1523     */
1524    public Period normalizedStandard(PeriodType type) {
1525        long millis = getMillis();  // no overflow can happen, even with Integer.MAX_VALUEs
1526        millis += (((long) getSeconds()) * ((long) DateTimeConstants.MILLIS_PER_SECOND));
1527        millis += (((long) getMinutes()) * ((long) DateTimeConstants.MILLIS_PER_MINUTE));
1528        millis += (((long) getHours()) * ((long) DateTimeConstants.MILLIS_PER_HOUR));
1529        millis += (((long) getDays()) * ((long) DateTimeConstants.MILLIS_PER_DAY));
1530        millis += (((long) getWeeks()) * ((long) DateTimeConstants.MILLIS_PER_WEEK));
1531        Period result = new Period(millis, DateTimeUtils.getPeriodType(type), ISOChronology.getInstanceUTC());
1532        int years = getYears();
1533        int months = getMonths();
1534        if (years != 0 || months != 0) {
1535            years = FieldUtils.safeAdd(years, months / 12);
1536            months = months % 12;
1537            if (years != 0) {
1538                result = result.withYears(years);
1539            }
1540            if (months != 0) {
1541                result = result.withMonths(months);
1542            }
1543        }
1544        return result;
1545    }
1546 
1547}

[all classes][org.joda.time]
EMMA 2.0.5312 (C) Vladimir Roubtsov