001 /*
002 * Copyright 2001-2005 Stephen Colebourne
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.joda.time;
017
018 import java.io.Serializable;
019
020 import org.joda.time.base.BasePeriod;
021 import org.joda.time.field.FieldUtils;
022 import org.joda.time.format.ISOPeriodFormat;
023
024 /**
025 * Standard mutable time period implementation.
026 * <p>
027 * A time period is divided into a number of fields, such as hours and seconds.
028 * Which fields are supported is defined by the PeriodType class.
029 * The default is the standard period type, which supports years, months, weeks, days,
030 * hours, minutes, seconds and millis.
031 * <p>
032 * When this time period is added to an instant, the effect is of adding each field in turn.
033 * As a result, this takes into account daylight savings time.
034 * Adding a time period of 1 day to the day before daylight savings starts will only add
035 * 23 hours rather than 24 to ensure that the time remains the same.
036 * If this is not the behaviour you want, then see {@link Duration}.
037 * <p>
038 * The definition of a period also affects the equals method. A period of 1
039 * day is not equal to a period of 24 hours, nor 1 hour equal to 60 minutes.
040 * This is because periods represent an abstracted definition of a time period
041 * (eg. a day may not actually be 24 hours, it might be 23 or 25 at daylight
042 * savings boundary). To compare the actual duration of two periods, convert
043 * both to durations using toDuration, an operation that emphasises that the
044 * result may differ according to the date you choose.
045 * <p>
046 * MutablePeriod is mutable and not thread-safe, unless concurrent threads
047 * are not invoking mutator methods.
048 *
049 * @author Brian S O'Neill
050 * @author Stephen Colebourne
051 * @since 1.0
052 * @see Period
053 */
054 public class MutablePeriod
055 extends BasePeriod
056 implements ReadWritablePeriod, Cloneable, Serializable {
057
058 /** Serialization version */
059 private static final long serialVersionUID = 3436451121567212165L;
060
061 /**
062 * Creates a zero-length period using the standard period type.
063 */
064 public MutablePeriod() {
065 super(0L, null, null);
066 }
067
068 /**
069 * Creates a zero-length period using the specified period type.
070 *
071 * @param type which set of fields this period supports
072 */
073 public MutablePeriod(PeriodType type) {
074 super(0L, type, null);
075 }
076
077 /**
078 * Create a period from a set of field values using the standard set of fields.
079 *
080 * @param hours amount of hours in this period
081 * @param minutes amount of minutes in this period
082 * @param seconds amount of seconds in this period
083 * @param millis amount of milliseconds in this period
084 */
085 public MutablePeriod(int hours, int minutes, int seconds, int millis) {
086 super(0, 0, 0, 0, hours, minutes, seconds, millis, PeriodType.standard());
087 }
088
089 /**
090 * Create a period from a set of field values using the standard set of fields.
091 *
092 * @param years amount of years in this period
093 * @param months amount of months in this period
094 * @param weeks amount of weeks in this period
095 * @param days amount of days in this period
096 * @param hours amount of hours in this period
097 * @param minutes amount of minutes in this period
098 * @param seconds amount of seconds in this period
099 * @param millis amount of milliseconds in this period
100 */
101 public MutablePeriod(int years, int months, int weeks, int days,
102 int hours, int minutes, int seconds, int millis) {
103 super(years, months, weeks, days, hours, minutes, seconds, millis, PeriodType.standard());
104 }
105
106 /**
107 * Create a period from a set of field values.
108 *
109 * @param years amount of years in this period, which must be zero if unsupported
110 * @param months amount of months in this period, which must be zero if unsupported
111 * @param weeks amount of weeks in this period, which must be zero if unsupported
112 * @param days amount of days in this period, which must be zero if unsupported
113 * @param hours amount of hours in this period, which must be zero if unsupported
114 * @param minutes amount of minutes in this period, which must be zero if unsupported
115 * @param seconds amount of seconds in this period, which must be zero if unsupported
116 * @param millis amount of milliseconds in this period, which must be zero if unsupported
117 * @param type which set of fields this period supports, null means AllType
118 * @throws IllegalArgumentException if an unsupported field's value is non-zero
119 */
120 public MutablePeriod(int years, int months, int weeks, int days,
121 int hours, int minutes, int seconds, int millis, PeriodType type) {
122 super(years, months, weeks, days, hours, minutes, seconds, millis, type);
123 }
124
125 /**
126 * Creates a period from the given millisecond duration using the standard
127 * set of fields.
128 * <p>
129 * Only precise fields in the period type will be used.
130 * For the standard period type this is the time fields only.
131 * Thus the year, month, week and day fields will not be populated.
132 * <p>
133 * If the duration is small, less than one day, then this method will perform
134 * as you might expect and split the fields evenly.
135 * <p>
136 * If the duration is larger than one day then all the remaining duration will
137 * be stored in the largest available precise field, hours in this case.
138 * <p>
139 * For example, a duration equal to (365 + 60 + 5) days will be converted to
140 * ((365 + 60 + 5) * 24) hours by this constructor.
141 * <p>
142 * For more control over the conversion process, you have two options:
143 * <ul>
144 * <li>convert the duration to an {@link Interval}, and from there obtain the period
145 * <li>specify a period type that contains precise definitions of the day and larger
146 * fields, such as the UTC or precise types.
147 * </ul>
148 *
149 * @param duration the duration, in milliseconds
150 */
151 public MutablePeriod(long duration) {
152 super(duration, null, null);
153 }
154
155 /**
156 * Creates a period from the given millisecond duration.
157 * <p>
158 * Only precise fields in the period type will be used.
159 * Imprecise fields will not be populated.
160 * <p>
161 * If the duration is small then this method will perform
162 * as you might expect and split the fields evenly.
163 * <p>
164 * If the duration is large then all the remaining duration will
165 * be stored in the largest available precise field.
166 * For details as to which fields are precise, review the period type javadoc.
167 *
168 * @param duration the duration, in milliseconds
169 * @param type which set of fields this period supports, null means standard
170 */
171 public MutablePeriod(long duration, PeriodType type) {
172 super(duration, type, null);
173 }
174
175 /**
176 * Creates a period from the given millisecond duration using the standard
177 * set of fields.
178 * <p>
179 * Only precise fields in the period type will be used.
180 * Imprecise fields will not be populated.
181 * <p>
182 * If the duration is small then this method will perform
183 * as you might expect and split the fields evenly.
184 * <p>
185 * If the duration is large then all the remaining duration will
186 * be stored in the largest available precise field.
187 * For details as to which fields are precise, review the period type javadoc.
188 *
189 * @param duration the duration, in milliseconds
190 * @param chronology the chronology to use to split the duration, null means ISO default
191 */
192 public MutablePeriod(long duration, Chronology chronology) {
193 super(duration, null, chronology);
194 }
195
196 /**
197 * Creates a period from the given millisecond duration.
198 * <p>
199 * Only precise fields in the period type will be used.
200 * Imprecise fields will not be populated.
201 * <p>
202 * If the duration is small then this method will perform
203 * as you might expect and split the fields evenly.
204 * <p>
205 * If the duration is large then all the remaining duration will
206 * be stored in the largest available precise field.
207 * For details as to which fields are precise, review the period type javadoc.
208 *
209 * @param duration the duration, in milliseconds
210 * @param type which set of fields this period supports, null means standard
211 * @param chronology the chronology to use to split the duration, null means ISO default
212 */
213 public MutablePeriod(long duration, PeriodType type, Chronology chronology) {
214 super(duration, type, chronology);
215 }
216
217 /**
218 * Creates a period from the given interval endpoints using the standard
219 * set of fields.
220 *
221 * @param startInstant interval start, in milliseconds
222 * @param endInstant interval end, in milliseconds
223 */
224 public MutablePeriod(long startInstant, long endInstant) {
225 super(startInstant, endInstant, null, null);
226 }
227
228 /**
229 * Creates a period from the given interval endpoints.
230 *
231 * @param startInstant interval start, in milliseconds
232 * @param endInstant interval end, in milliseconds
233 * @param type which set of fields this period supports, null means standard
234 */
235 public MutablePeriod(long startInstant, long endInstant, PeriodType type) {
236 super(startInstant, endInstant, type, null);
237 }
238
239 /**
240 * Creates a period from the given interval endpoints using the standard
241 * set of fields.
242 *
243 * @param startInstant interval start, in milliseconds
244 * @param endInstant interval end, in milliseconds
245 * @param chrono the chronology to use, null means ISO in default zone
246 */
247 public MutablePeriod(long startInstant, long endInstant, Chronology chrono) {
248 super(startInstant, endInstant, null, chrono);
249 }
250
251 /**
252 * Creates a period from the given interval endpoints.
253 *
254 * @param startInstant interval start, in milliseconds
255 * @param endInstant interval end, in milliseconds
256 * @param type which set of fields this period supports, null means standard
257 * @param chrono the chronology to use, null means ISO in default zone
258 */
259 public MutablePeriod(long startInstant, long endInstant, PeriodType type, Chronology chrono) {
260 super(startInstant, endInstant, type, chrono);
261 }
262
263 /**
264 * Creates a period from the given interval endpoints using the standard
265 * set of fields.
266 * <p>
267 * The chronology of the start instant is used, unless that is null when the
268 * chronology of the end instant is used instead.
269 *
270 * @param startInstant interval start, null means now
271 * @param endInstant interval end, null means now
272 */
273 public MutablePeriod(ReadableInstant startInstant, ReadableInstant endInstant) {
274 super(startInstant, endInstant, null);
275 }
276
277 /**
278 * Creates a period from the given interval endpoints.
279 * <p>
280 * The chronology of the start instant is used, unless that is null when the
281 * chronology of the end instant is used instead.
282 *
283 * @param startInstant interval start, null means now
284 * @param endInstant interval end, null means now
285 * @param type which set of fields this period supports, null means AllType
286 */
287 public MutablePeriod(ReadableInstant startInstant, ReadableInstant endInstant, PeriodType type) {
288 super(startInstant, endInstant, type);
289 }
290
291 /**
292 * Creates a period from the given start point and the duration.
293 *
294 * @param startInstant the interval start, null means now
295 * @param duration the duration of the interval, null means zero-length
296 */
297 public MutablePeriod(ReadableInstant startInstant, ReadableDuration duration) {
298 super(startInstant, duration, null);
299 }
300
301 /**
302 * Creates a period from the given start point and the duration.
303 *
304 * @param startInstant the interval start, null means now
305 * @param duration the duration of the interval, null means zero-length
306 * @param type which set of fields this period supports, null means standard
307 */
308 public MutablePeriod(ReadableInstant startInstant, ReadableDuration duration, PeriodType type) {
309 super(startInstant, duration, type);
310 }
311
312 /**
313 * Creates a period from the given duration and end point.
314 *
315 * @param duration the duration of the interval, null means zero-length
316 * @param endInstant the interval end, null means now
317 */
318 public MutablePeriod(ReadableDuration duration, ReadableInstant endInstant) {
319 super(duration, endInstant, null);
320 }
321
322 /**
323 * Creates a period from the given duration and end point.
324 *
325 * @param duration the duration of the interval, null means zero-length
326 * @param endInstant the interval end, null means now
327 * @param type which set of fields this period supports, null means standard
328 */
329 public MutablePeriod(ReadableDuration duration, ReadableInstant endInstant, PeriodType type) {
330 super(duration, endInstant, type);
331 }
332
333 /**
334 * Creates a period by converting or copying from another object.
335 * <p>
336 * The recognised object types are defined in
337 * {@link org.joda.time.convert.ConverterManager ConverterManager} and
338 * include ReadablePeriod, ReadableInterval and String.
339 * The String formats are described by {@link ISOPeriodFormat#standard()}.
340 *
341 * @param period period to convert
342 * @throws IllegalArgumentException if period is invalid
343 * @throws UnsupportedOperationException if an unsupported field's value is non-zero
344 */
345 public MutablePeriod(Object period) {
346 super(period, null, null);
347 }
348
349 /**
350 * Creates a period by converting or copying from another object.
351 * <p>
352 * The recognised object types are defined in
353 * {@link org.joda.time.convert.ConverterManager ConverterManager} and
354 * include ReadablePeriod, ReadableInterval and String.
355 * The String formats are described by {@link ISOPeriodFormat#standard()}.
356 *
357 * @param period period to convert
358 * @param type which set of fields this period supports, null means use converter
359 * @throws IllegalArgumentException if period is invalid
360 * @throws UnsupportedOperationException if an unsupported field's value is non-zero
361 */
362 public MutablePeriod(Object period, PeriodType type) {
363 super(period, type, null);
364 }
365
366 /**
367 * Creates a period by converting or copying from another object.
368 * <p>
369 * The recognised object types are defined in
370 * {@link org.joda.time.convert.ConverterManager ConverterManager} and
371 * include ReadablePeriod, ReadableInterval and String.
372 * The String formats are described by {@link ISOPeriodFormat#standard()}.
373 *
374 * @param period period to convert
375 * @param chrono the chronology to use, null means ISO in default zone
376 * @throws IllegalArgumentException if period is invalid
377 * @throws UnsupportedOperationException if an unsupported field's value is non-zero
378 */
379 public MutablePeriod(Object period, Chronology chrono) {
380 super(period, null, chrono);
381 }
382
383 /**
384 * Creates a period by converting or copying from another object.
385 * <p>
386 * The recognised object types are defined in
387 * {@link org.joda.time.convert.ConverterManager ConverterManager} and
388 * include ReadablePeriod, ReadableInterval and String.
389 * The String formats are described by {@link ISOPeriodFormat#standard()}.
390 *
391 * @param period period to convert
392 * @param type which set of fields this period supports, null means use converter
393 * @param chrono the chronology to use, null means ISO in default zone
394 * @throws IllegalArgumentException if period is invalid
395 * @throws UnsupportedOperationException if an unsupported field's value is non-zero
396 */
397 public MutablePeriod(Object period, PeriodType type, Chronology chrono) {
398 super(period, type, chrono);
399 }
400
401 //-----------------------------------------------------------------------
402 /**
403 * Clears the period, setting all values back to zero.
404 */
405 public void clear() {
406 super.setValues(new int[size()]);
407 }
408
409 /**
410 * Sets the value of one of the fields by index.
411 *
412 * @param index the field index
413 * @param value the new value for the field
414 * @throws IndexOutOfBoundsException if the index is invalid
415 */
416 public void setValue(int index, int value) {
417 super.setValue(index, value);
418 }
419
420 /**
421 * Sets the value of one of the fields.
422 * <p>
423 * The field type specified must be one of those that is supported by the period.
424 *
425 * @param field a DurationFieldType instance that is supported by this period, not null
426 * @param value the new value for the field
427 * @throws IllegalArgumentException if the field is null or not supported
428 */
429 public void set(DurationFieldType field, int value) {
430 super.setField(field, value);
431 }
432
433 /**
434 * Sets all the fields in one go from another ReadablePeriod.
435 *
436 * @param period the period to set, null means zero length period
437 * @throws IllegalArgumentException if an unsupported field's value is non-zero
438 */
439 public void setPeriod(ReadablePeriod period) {
440 super.setPeriod(period);
441 }
442
443 /**
444 * Sets all the fields in one go.
445 *
446 * @param years amount of years in this period, which must be zero if unsupported
447 * @param months amount of months in this period, which must be zero if unsupported
448 * @param weeks amount of weeks in this period, which must be zero if unsupported
449 * @param days amount of days in this period, which must be zero if unsupported
450 * @param hours amount of hours in this period, which must be zero if unsupported
451 * @param minutes amount of minutes in this period, which must be zero if unsupported
452 * @param seconds amount of seconds in this period, which must be zero if unsupported
453 * @param millis amount of milliseconds in this period, which must be zero if unsupported
454 * @throws IllegalArgumentException if an unsupported field's value is non-zero
455 */
456 public void setPeriod(int years, int months, int weeks, int days,
457 int hours, int minutes, int seconds, int millis) {
458 super.setPeriod(years, months, weeks, days, hours, minutes, seconds, millis);
459 }
460
461 /**
462 * Sets all the fields in one go from an interval using the ISO chronology
463 * and dividing the fields using the period type.
464 *
465 * @param interval the interval to set, null means zero length
466 * @throws ArithmeticException if the set exceeds the capacity of the period
467 */
468 public void setPeriod(ReadableInterval interval) {
469 if (interval == null) {
470 setPeriod(0L);
471 } else {
472 Chronology chrono = DateTimeUtils.getChronology(interval.getChronology());
473 setPeriod(interval.getStartMillis(), interval.getEndMillis(), chrono);
474 }
475 }
476
477 /**
478 * Sets all the fields in one go from two instants representing an interval.
479 * <p>
480 * The chronology of the start instant is used, unless that is null when the
481 * chronology of the end instant is used instead.
482 *
483 * @param start the start instant, null means now
484 * @param end the end instant, null means now
485 * @throws ArithmeticException if the set exceeds the capacity of the period
486 */
487 public void setPeriod(ReadableInstant start, ReadableInstant end) {
488 if (start == end) {
489 setPeriod(0L);
490 } else {
491 long startMillis = DateTimeUtils.getInstantMillis(start);
492 long endMillis = DateTimeUtils.getInstantMillis(end);
493 Chronology chrono = DateTimeUtils.getIntervalChronology(start, end);
494 setPeriod(startMillis, endMillis, chrono);
495 }
496 }
497
498 /**
499 * Sets all the fields in one go from a millisecond interval using ISOChronology
500 * and dividing the fields using the period type.
501 *
502 * @param startInstant interval start, in milliseconds
503 * @param endInstant interval end, in milliseconds
504 * @throws ArithmeticException if the set exceeds the capacity of the period
505 */
506 public void setPeriod(long startInstant, long endInstant) {
507 setPeriod(startInstant, endInstant, null);
508 }
509
510 /**
511 * Sets all the fields in one go from a millisecond interval.
512 *
513 * @param startInstant interval start, in milliseconds
514 * @param endInstant interval end, in milliseconds
515 * @param chrono the chronology to use, not null
516 * @throws ArithmeticException if the set exceeds the capacity of the period
517 */
518 public void setPeriod(long startInstant, long endInstant, Chronology chrono) {
519 chrono = DateTimeUtils.getChronology(chrono);
520 setValues(chrono.get(this, startInstant, endInstant));
521 }
522
523 /**
524 * Sets all the fields in one go from a duration dividing the
525 * fields using the period type.
526 * <p>
527 * When dividing the duration, only precise fields in the period type will be used.
528 * For large durations, all the remaining duration will be stored in the largest
529 * available precise field.
530 *
531 * @param duration the duration to set, null means zero length
532 * @throws ArithmeticException if the set exceeds the capacity of the period
533 */
534 public void setPeriod(ReadableDuration duration) {
535 setPeriod(duration, null);
536 }
537
538 /**
539 * Sets all the fields in one go from a duration dividing the
540 * fields using the period type.
541 * <p>
542 * When dividing the duration, only precise fields in the period type will be used.
543 * For large durations, all the remaining duration will be stored in the largest
544 * available precise field.
545 *
546 * @param duration the duration to set, null means zero length
547 * @param chrono the chronology to use, null means ISO default
548 * @throws ArithmeticException if the set exceeds the capacity of the period
549 */
550 public void setPeriod(ReadableDuration duration, Chronology chrono) {
551 long durationMillis = DateTimeUtils.getDurationMillis(duration);
552 setPeriod(durationMillis, chrono);
553 }
554
555 /**
556 * Sets all the fields in one go from a millisecond duration dividing the
557 * fields using the period type.
558 * <p>
559 * When dividing the duration, only precise fields in the period type will be used.
560 * For large durations, all the remaining duration will be stored in the largest
561 * available precise field.
562 *
563 * @param duration the duration, in milliseconds
564 * @throws ArithmeticException if the set exceeds the capacity of the period
565 */
566 public void setPeriod(long duration) {
567 setPeriod(duration, null);
568 }
569
570 /**
571 * Sets all the fields in one go from a millisecond duration.
572 * <p>
573 * When dividing the duration, only precise fields in the period type will be used.
574 * For large durations, all the remaining duration will be stored in the largest
575 * available precise field.
576 *
577 * @param duration the duration, in milliseconds
578 * @param chrono the chronology to use, not null
579 * @throws ArithmeticException if the set exceeds the capacity of the period
580 */
581 public void setPeriod(long duration, Chronology chrono) {
582 chrono = DateTimeUtils.getChronology(chrono);
583 setValues(chrono.get(this, duration));
584 }
585
586 //-----------------------------------------------------------------------
587 /**
588 * Adds to the value of one of the fields.
589 * <p>
590 * The field type specified must be one of those that is supported by the period.
591 *
592 * @param field a DurationFieldType instance that is supported by this period, not null
593 * @param value the value to add to the field
594 * @throws IllegalArgumentException if the field is null or not supported
595 */
596 public void add(DurationFieldType field, int value) {
597 super.addField(field, value);
598 }
599
600 /**
601 * Adds a period to this one by adding each field in turn.
602 *
603 * @param period the period to add, null means add nothing
604 * @throws IllegalArgumentException if the period being added contains a field
605 * not supported by this period
606 * @throws ArithmeticException if the addition exceeds the capacity of the period
607 */
608 public void add(ReadablePeriod period) {
609 super.addPeriod(period);
610 }
611
612 /**
613 * Adds to each field of this period.
614 *
615 * @param years amount of years to add to this period, which must be zero if unsupported
616 * @param months amount of months to add to this period, which must be zero if unsupported
617 * @param weeks amount of weeks to add to this period, which must be zero if unsupported
618 * @param days amount of days to add to this period, which must be zero if unsupported
619 * @param hours amount of hours to add to this period, which must be zero if unsupported
620 * @param minutes amount of minutes to add to this period, which must be zero if unsupported
621 * @param seconds amount of seconds to add to this period, which must be zero if unsupported
622 * @param millis amount of milliseconds to add to this period, which must be zero if unsupported
623 * @throws IllegalArgumentException if the period being added contains a field
624 * not supported by this period
625 * @throws ArithmeticException if the addition exceeds the capacity of the period
626 */
627 public void add(int years, int months, int weeks, int days,
628 int hours, int minutes, int seconds, int millis) {
629 setPeriod(
630 FieldUtils.safeAdd(getYears(), years),
631 FieldUtils.safeAdd(getMonths(), months),
632 FieldUtils.safeAdd(getWeeks(), weeks),
633 FieldUtils.safeAdd(getDays(), days),
634 FieldUtils.safeAdd(getHours(), hours),
635 FieldUtils.safeAdd(getMinutes(), minutes),
636 FieldUtils.safeAdd(getSeconds(), seconds),
637 FieldUtils.safeAdd(getMillis(), millis)
638 );
639 }
640
641 /**
642 * Adds an interval to this one by dividing the interval into
643 * fields and calling {@link #add(ReadablePeriod)}.
644 *
645 * @param interval the interval to add, null means add nothing
646 * @throws ArithmeticException if the addition exceeds the capacity of the period
647 */
648 public void add(ReadableInterval interval) {
649 if (interval != null) {
650 add(interval.toPeriod(getPeriodType()));
651 }
652 }
653
654 /**
655 * Adds a duration to this one by dividing the duration into
656 * fields and calling {@link #add(ReadablePeriod)}.
657 *
658 * @param duration the duration to add, null means add nothing
659 * @throws ArithmeticException if the addition exceeds the capacity of the period
660 */
661 public void add(ReadableDuration duration) {
662 if (duration != null) {
663 add(new Period(duration.getMillis(), getPeriodType()));
664 }
665 }
666
667 /**
668 * Adds a millisecond duration to this one by dividing the duration into
669 * fields and calling {@link #add(ReadablePeriod)}.
670 * <p>
671 * When dividing the duration, only precise fields in the period type will be used.
672 * For large durations, all the remaining duration will be stored in the largest
673 * available precise field.
674 *
675 * @param duration the duration, in milliseconds
676 * @throws ArithmeticException if the addition exceeds the capacity of the period
677 */
678 public void add(long duration) {
679 add(new Period(duration, getPeriodType()));
680 }
681
682 /**
683 * Adds a millisecond duration to this one by dividing the duration into
684 * fields and calling {@link #add(ReadablePeriod)}.
685 * <p>
686 * When dividing the duration, only precise fields in the period type will be used.
687 * For large durations, all the remaining duration will be stored in the largest
688 * available precise field.
689 *
690 * @param duration the duration, in milliseconds
691 * @param chrono the chronology to use, null means ISO default
692 * @throws ArithmeticException if the addition exceeds the capacity of the period
693 */
694 public void add(long duration, Chronology chrono) {
695 add(new Period(duration, getPeriodType(), chrono));
696 }
697
698 //-----------------------------------------------------------------------
699 /**
700 * Merges all the fields from the specified period into this one.
701 * <p>
702 * Fields that are not present in the specified period are left unaltered.
703 *
704 * @param period the period to set, null ignored
705 * @throws IllegalArgumentException if an unsupported field's value is non-zero
706 */
707 public void mergePeriod(ReadablePeriod period) {
708 super.mergePeriod(period);
709 }
710
711 //-----------------------------------------------------------------------
712 /**
713 * Gets the years field part of the period.
714 *
715 * @return the number of years in the period, zero if unsupported
716 */
717 public int getYears() {
718 return getPeriodType().getIndexedField(this, PeriodType.YEAR_INDEX);
719 }
720
721 /**
722 * Gets the months field part of the period.
723 *
724 * @return the number of months in the period, zero if unsupported
725 */
726 public int getMonths() {
727 return getPeriodType().getIndexedField(this, PeriodType.MONTH_INDEX);
728 }
729
730 /**
731 * Gets the weeks field part of the period.
732 *
733 * @return the number of weeks in the period, zero if unsupported
734 */
735 public int getWeeks() {
736 return getPeriodType().getIndexedField(this, PeriodType.WEEK_INDEX);
737 }
738
739 /**
740 * Gets the days field part of the period.
741 *
742 * @return the number of days in the period, zero if unsupported
743 */
744 public int getDays() {
745 return getPeriodType().getIndexedField(this, PeriodType.DAY_INDEX);
746 }
747
748 //-----------------------------------------------------------------------
749 /**
750 * Gets the hours field part of the period.
751 *
752 * @return the number of hours in the period, zero if unsupported
753 */
754 public int getHours() {
755 return getPeriodType().getIndexedField(this, PeriodType.HOUR_INDEX);
756 }
757
758 /**
759 * Gets the minutes field part of the period.
760 *
761 * @return the number of minutes in the period, zero if unsupported
762 */
763 public int getMinutes() {
764 return getPeriodType().getIndexedField(this, PeriodType.MINUTE_INDEX);
765 }
766
767 /**
768 * Gets the seconds field part of the period.
769 *
770 * @return the number of seconds in the period, zero if unsupported
771 */
772 public int getSeconds() {
773 return getPeriodType().getIndexedField(this, PeriodType.SECOND_INDEX);
774 }
775
776 /**
777 * Gets the millis field part of the period.
778 *
779 * @return the number of millis in the period, zero if unsupported
780 */
781 public int getMillis() {
782 return getPeriodType().getIndexedField(this, PeriodType.MILLI_INDEX);
783 }
784
785 //-----------------------------------------------------------------------
786 /**
787 * Sets the number of years of the period.
788 *
789 * @param years the number of years
790 * @throws IllegalArgumentException if field is not supported and the value is non-zero
791 */
792 public void setYears(int years) {
793 super.setField(DurationFieldType.years(), years);
794 }
795
796 /**
797 * Adds the specified years to the number of years in the period.
798 *
799 * @param years the number of years
800 * @throws IllegalArgumentException if field is not supported and the value is non-zero
801 * @throws ArithmeticException if the addition exceeds the capacity of the period
802 */
803 public void addYears(int years) {
804 super.addField(DurationFieldType.years(), years);
805 }
806
807 //-----------------------------------------------------------------------
808 /**
809 * Sets the number of months of the period.
810 *
811 * @param months the number of months
812 * @throws IllegalArgumentException if field is not supported and the value is non-zero
813 */
814 public void setMonths(int months) {
815 super.setField(DurationFieldType.months(), months);
816 }
817
818 /**
819 * Adds the specified months to the number of months in the period.
820 *
821 * @param months the number of months
822 * @throws IllegalArgumentException if field is not supported and the value is non-zero
823 * @throws ArithmeticException if the addition exceeds the capacity of the period
824 */
825 public void addMonths(int months) {
826 super.addField(DurationFieldType.months(), months);
827 }
828
829 //-----------------------------------------------------------------------
830 /**
831 * Sets the number of weeks of the period.
832 *
833 * @param weeks the number of weeks
834 * @throws IllegalArgumentException if field is not supported and the value is non-zero
835 */
836 public void setWeeks(int weeks) {
837 super.setField(DurationFieldType.weeks(), weeks);
838 }
839
840 /**
841 * Adds the specified weeks to the number of weeks in the period.
842 *
843 * @param weeks the number of weeks
844 * @throws IllegalArgumentException if field is not supported and the value is non-zero
845 * @throws ArithmeticException if the addition exceeds the capacity of the period
846 */
847 public void addWeeks(int weeks) {
848 super.addField(DurationFieldType.weeks(), weeks);
849 }
850
851 //-----------------------------------------------------------------------
852 /**
853 * Sets the number of days of the period.
854 *
855 * @param days the number of days
856 * @throws IllegalArgumentException if field is not supported and the value is non-zero
857 */
858 public void setDays(int days) {
859 super.setField(DurationFieldType.days(), days);
860 }
861
862 /**
863 * Adds the specified days to the number of days in the period.
864 *
865 * @param days the number of days
866 * @throws IllegalArgumentException if field is not supported and the value is non-zero
867 * @throws ArithmeticException if the addition exceeds the capacity of the period
868 */
869 public void addDays(int days) {
870 super.addField(DurationFieldType.days(), days);
871 }
872
873 //-----------------------------------------------------------------------
874 /**
875 * Sets the number of hours of the period.
876 *
877 * @param hours the number of hours
878 * @throws IllegalArgumentException if field is not supported and the value is non-zero
879 */
880 public void setHours(int hours) {
881 super.setField(DurationFieldType.hours(), hours);
882 }
883
884 /**
885 * Adds the specified hours to the number of hours in the period.
886 *
887 * @param hours the number of hours
888 * @throws IllegalArgumentException if field is not supported and the value is non-zero
889 * @throws ArithmeticException if the addition exceeds the capacity of the period
890 */
891 public void addHours(int hours) {
892 super.addField(DurationFieldType.hours(), hours);
893 }
894
895 //-----------------------------------------------------------------------
896 /**
897 * Sets the number of minutes of the period.
898 *
899 * @param minutes the number of minutes
900 * @throws IllegalArgumentException if field is not supported and the value is non-zero
901 */
902 public void setMinutes(int minutes) {
903 super.setField(DurationFieldType.minutes(), minutes);
904 }
905
906 /**
907 * Adds the specified minutes to the number of minutes in the period.
908 *
909 * @param minutes the number of minutes
910 * @throws IllegalArgumentException if field is not supported and the value is non-zero
911 * @throws ArithmeticException if the addition exceeds the capacity of the period
912 */
913 public void addMinutes(int minutes) {
914 super.addField(DurationFieldType.minutes(), minutes);
915 }
916
917 //-----------------------------------------------------------------------
918 /**
919 * Sets the number of seconds of the period.
920 *
921 * @param seconds the number of seconds
922 * @throws IllegalArgumentException if field is not supported and the value is non-zero
923 */
924 public void setSeconds(int seconds) {
925 super.setField(DurationFieldType.seconds(), seconds);
926 }
927
928 /**
929 * Adds the specified seconds to the number of seconds in the period.
930 *
931 * @param seconds the number of seconds
932 * @throws IllegalArgumentException if field is not supported and the value is non-zero
933 * @throws ArithmeticException if the addition exceeds the capacity of the period
934 */
935 public void addSeconds(int seconds) {
936 super.addField(DurationFieldType.seconds(), seconds);
937 }
938
939 //-----------------------------------------------------------------------
940 /**
941 * Sets the number of millis of the period.
942 *
943 * @param millis the number of millis
944 * @throws IllegalArgumentException if field is not supported and the value is non-zero
945 */
946 public void setMillis(int millis) {
947 super.setField(DurationFieldType.millis(), millis);
948 }
949
950 /**
951 * Adds the specified millis to the number of millis in the period.
952 *
953 * @param millis the number of millis
954 * @throws IllegalArgumentException if field is not supported and the value is non-zero
955 * @throws ArithmeticException if the addition exceeds the capacity of the period
956 */
957 public void addMillis(int millis) {
958 super.addField(DurationFieldType.millis(), millis);
959 }
960
961 // Misc
962 //-----------------------------------------------------------------------
963 /**
964 * Clone this object without having to cast the returned object.
965 *
966 * @return a clone of the this object.
967 */
968 public MutablePeriod copy() {
969 return (MutablePeriod) clone();
970 }
971
972 /**
973 * Clone this object.
974 *
975 * @return a clone of this object.
976 */
977 public Object clone() {
978 try {
979 return super.clone();
980 } catch (CloneNotSupportedException ex) {
981 throw new InternalError("Clone error");
982 }
983 }
984
985 }