0001: /*
0002: * Copyright 2001-2005 Stephen Colebourne
0003: *
0004: * Licensed under the Apache License, Version 2.0 (the "License");
0005: * you may not use this file except in compliance with the License.
0006: * You may obtain a copy of the License at
0007: *
0008: * http://www.apache.org/licenses/LICENSE-2.0
0009: *
0010: * Unless required by applicable law or agreed to in writing, software
0011: * distributed under the License is distributed on an "AS IS" BASIS,
0012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013: * See the License for the specific language governing permissions and
0014: * limitations under the License.
0015: */
0016: package org.joda.time;
0017:
0018: import java.io.Serializable;
0019:
0020: import org.joda.time.base.BasePeriod;
0021: import org.joda.time.field.FieldUtils;
0022: import org.joda.time.format.ISOPeriodFormat;
0023:
0024: /**
0025: * Standard mutable time period implementation.
0026: * <p>
0027: * A time period is divided into a number of fields, such as hours and seconds.
0028: * Which fields are supported is defined by the PeriodType class.
0029: * The default is the standard period type, which supports years, months, weeks, days,
0030: * hours, minutes, seconds and millis.
0031: * <p>
0032: * When this time period is added to an instant, the effect is of adding each field in turn.
0033: * As a result, this takes into account daylight savings time.
0034: * Adding a time period of 1 day to the day before daylight savings starts will only add
0035: * 23 hours rather than 24 to ensure that the time remains the same.
0036: * If this is not the behaviour you want, then see {@link Duration}.
0037: * <p>
0038: * The definition of a period also affects the equals method. A period of 1
0039: * day is not equal to a period of 24 hours, nor 1 hour equal to 60 minutes.
0040: * This is because periods represent an abstracted definition of a time period
0041: * (eg. a day may not actually be 24 hours, it might be 23 or 25 at daylight
0042: * savings boundary). To compare the actual duration of two periods, convert
0043: * both to durations using toDuration, an operation that emphasises that the
0044: * result may differ according to the date you choose.
0045: * <p>
0046: * MutablePeriod is mutable and not thread-safe, unless concurrent threads
0047: * are not invoking mutator methods.
0048: *
0049: * @author Brian S O'Neill
0050: * @author Stephen Colebourne
0051: * @since 1.0
0052: * @see Period
0053: */
0054: public class MutablePeriod extends BasePeriod implements
0055: ReadWritablePeriod, Cloneable, Serializable {
0056:
0057: /** Serialization version */
0058: private static final long serialVersionUID = 3436451121567212165L;
0059:
0060: /**
0061: * Creates a zero-length period using the standard period type.
0062: */
0063: public MutablePeriod() {
0064: super (0L, null, null);
0065: }
0066:
0067: /**
0068: * Creates a zero-length period using the specified period type.
0069: *
0070: * @param type which set of fields this period supports
0071: */
0072: public MutablePeriod(PeriodType type) {
0073: super (0L, type, null);
0074: }
0075:
0076: /**
0077: * Create a period from a set of field values using the standard set of fields.
0078: *
0079: * @param hours amount of hours in this period
0080: * @param minutes amount of minutes in this period
0081: * @param seconds amount of seconds in this period
0082: * @param millis amount of milliseconds in this period
0083: */
0084: public MutablePeriod(int hours, int minutes, int seconds, int millis) {
0085: super (0, 0, 0, 0, hours, minutes, seconds, millis, PeriodType
0086: .standard());
0087: }
0088:
0089: /**
0090: * Create a period from a set of field values using the standard set of fields.
0091: *
0092: * @param years amount of years in this period
0093: * @param months amount of months in this period
0094: * @param weeks amount of weeks in this period
0095: * @param days amount of days in this period
0096: * @param hours amount of hours in this period
0097: * @param minutes amount of minutes in this period
0098: * @param seconds amount of seconds in this period
0099: * @param millis amount of milliseconds in this period
0100: */
0101: public MutablePeriod(int years, int months, int weeks, int days,
0102: int hours, int minutes, int seconds, int millis) {
0103: super (years, months, weeks, days, hours, minutes, seconds,
0104: millis, PeriodType.standard());
0105: }
0106:
0107: /**
0108: * Create a period from a set of field values.
0109: *
0110: * @param years amount of years in this period, which must be zero if unsupported
0111: * @param months amount of months in this period, which must be zero if unsupported
0112: * @param weeks amount of weeks in this period, which must be zero if unsupported
0113: * @param days amount of days in this period, which must be zero if unsupported
0114: * @param hours amount of hours in this period, which must be zero if unsupported
0115: * @param minutes amount of minutes in this period, which must be zero if unsupported
0116: * @param seconds amount of seconds in this period, which must be zero if unsupported
0117: * @param millis amount of milliseconds in this period, which must be zero if unsupported
0118: * @param type which set of fields this period supports, null means AllType
0119: * @throws IllegalArgumentException if an unsupported field's value is non-zero
0120: */
0121: public MutablePeriod(int years, int months, int weeks, int days,
0122: int hours, int minutes, int seconds, int millis,
0123: PeriodType type) {
0124: super (years, months, weeks, days, hours, minutes, seconds,
0125: millis, type);
0126: }
0127:
0128: /**
0129: * Creates a period from the given millisecond duration using the standard
0130: * set of fields.
0131: * <p>
0132: * Only precise fields in the period type will be used.
0133: * For the standard period type this is the time fields only.
0134: * Thus the year, month, week and day fields will not be populated.
0135: * <p>
0136: * If the duration is small, less than one day, then this method will perform
0137: * as you might expect and split the fields evenly.
0138: * <p>
0139: * If the duration is larger than one day then all the remaining duration will
0140: * be stored in the largest available precise field, hours in this case.
0141: * <p>
0142: * For example, a duration equal to (365 + 60 + 5) days will be converted to
0143: * ((365 + 60 + 5) * 24) hours by this constructor.
0144: * <p>
0145: * For more control over the conversion process, you have two options:
0146: * <ul>
0147: * <li>convert the duration to an {@link Interval}, and from there obtain the period
0148: * <li>specify a period type that contains precise definitions of the day and larger
0149: * fields, such as the UTC or precise types.
0150: * </ul>
0151: *
0152: * @param duration the duration, in milliseconds
0153: */
0154: public MutablePeriod(long duration) {
0155: super (duration, null, null);
0156: }
0157:
0158: /**
0159: * Creates a period from the given millisecond duration.
0160: * <p>
0161: * Only precise fields in the period type will be used.
0162: * Imprecise fields will not be populated.
0163: * <p>
0164: * If the duration is small then this method will perform
0165: * as you might expect and split the fields evenly.
0166: * <p>
0167: * If the duration is large then all the remaining duration will
0168: * be stored in the largest available precise field.
0169: * For details as to which fields are precise, review the period type javadoc.
0170: *
0171: * @param duration the duration, in milliseconds
0172: * @param type which set of fields this period supports, null means standard
0173: */
0174: public MutablePeriod(long duration, PeriodType type) {
0175: super (duration, type, null);
0176: }
0177:
0178: /**
0179: * Creates a period from the given millisecond duration using the standard
0180: * set of fields.
0181: * <p>
0182: * Only precise fields in the period type will be used.
0183: * Imprecise fields will not be populated.
0184: * <p>
0185: * If the duration is small then this method will perform
0186: * as you might expect and split the fields evenly.
0187: * <p>
0188: * If the duration is large then all the remaining duration will
0189: * be stored in the largest available precise field.
0190: * For details as to which fields are precise, review the period type javadoc.
0191: *
0192: * @param duration the duration, in milliseconds
0193: * @param chronology the chronology to use to split the duration, null means ISO default
0194: */
0195: public MutablePeriod(long duration, Chronology chronology) {
0196: super (duration, null, chronology);
0197: }
0198:
0199: /**
0200: * Creates a period from the given millisecond duration.
0201: * <p>
0202: * Only precise fields in the period type will be used.
0203: * Imprecise fields will not be populated.
0204: * <p>
0205: * If the duration is small then this method will perform
0206: * as you might expect and split the fields evenly.
0207: * <p>
0208: * If the duration is large then all the remaining duration will
0209: * be stored in the largest available precise field.
0210: * For details as to which fields are precise, review the period type javadoc.
0211: *
0212: * @param duration the duration, in milliseconds
0213: * @param type which set of fields this period supports, null means standard
0214: * @param chronology the chronology to use to split the duration, null means ISO default
0215: */
0216: public MutablePeriod(long duration, PeriodType type,
0217: Chronology chronology) {
0218: super (duration, type, chronology);
0219: }
0220:
0221: /**
0222: * Creates a period from the given interval endpoints using the standard
0223: * set of fields.
0224: *
0225: * @param startInstant interval start, in milliseconds
0226: * @param endInstant interval end, in milliseconds
0227: */
0228: public MutablePeriod(long startInstant, long endInstant) {
0229: super (startInstant, endInstant, null, null);
0230: }
0231:
0232: /**
0233: * Creates a period from the given interval endpoints.
0234: *
0235: * @param startInstant interval start, in milliseconds
0236: * @param endInstant interval end, in milliseconds
0237: * @param type which set of fields this period supports, null means standard
0238: */
0239: public MutablePeriod(long startInstant, long endInstant,
0240: PeriodType type) {
0241: super (startInstant, endInstant, type, null);
0242: }
0243:
0244: /**
0245: * Creates a period from the given interval endpoints using the standard
0246: * set of fields.
0247: *
0248: * @param startInstant interval start, in milliseconds
0249: * @param endInstant interval end, in milliseconds
0250: * @param chrono the chronology to use, null means ISO in default zone
0251: */
0252: public MutablePeriod(long startInstant, long endInstant,
0253: Chronology chrono) {
0254: super (startInstant, endInstant, null, chrono);
0255: }
0256:
0257: /**
0258: * Creates a period from the given interval endpoints.
0259: *
0260: * @param startInstant interval start, in milliseconds
0261: * @param endInstant interval end, in milliseconds
0262: * @param type which set of fields this period supports, null means standard
0263: * @param chrono the chronology to use, null means ISO in default zone
0264: */
0265: public MutablePeriod(long startInstant, long endInstant,
0266: PeriodType type, Chronology chrono) {
0267: super (startInstant, endInstant, type, chrono);
0268: }
0269:
0270: /**
0271: * Creates a period from the given interval endpoints using the standard
0272: * set of fields.
0273: * <p>
0274: * The chronology of the start instant is used, unless that is null when the
0275: * chronology of the end instant is used instead.
0276: *
0277: * @param startInstant interval start, null means now
0278: * @param endInstant interval end, null means now
0279: */
0280: public MutablePeriod(ReadableInstant startInstant,
0281: ReadableInstant endInstant) {
0282: super (startInstant, endInstant, null);
0283: }
0284:
0285: /**
0286: * Creates a period from the given interval endpoints.
0287: * <p>
0288: * The chronology of the start instant is used, unless that is null when the
0289: * chronology of the end instant is used instead.
0290: *
0291: * @param startInstant interval start, null means now
0292: * @param endInstant interval end, null means now
0293: * @param type which set of fields this period supports, null means AllType
0294: */
0295: public MutablePeriod(ReadableInstant startInstant,
0296: ReadableInstant endInstant, PeriodType type) {
0297: super (startInstant, endInstant, type);
0298: }
0299:
0300: /**
0301: * Creates a period from the given start point and the duration.
0302: *
0303: * @param startInstant the interval start, null means now
0304: * @param duration the duration of the interval, null means zero-length
0305: */
0306: public MutablePeriod(ReadableInstant startInstant,
0307: ReadableDuration duration) {
0308: super (startInstant, duration, null);
0309: }
0310:
0311: /**
0312: * Creates a period from the given start point and the duration.
0313: *
0314: * @param startInstant the interval start, null means now
0315: * @param duration the duration of the interval, null means zero-length
0316: * @param type which set of fields this period supports, null means standard
0317: */
0318: public MutablePeriod(ReadableInstant startInstant,
0319: ReadableDuration duration, PeriodType type) {
0320: super (startInstant, duration, type);
0321: }
0322:
0323: /**
0324: * Creates a period from the given duration and end point.
0325: *
0326: * @param duration the duration of the interval, null means zero-length
0327: * @param endInstant the interval end, null means now
0328: */
0329: public MutablePeriod(ReadableDuration duration,
0330: ReadableInstant endInstant) {
0331: super (duration, endInstant, null);
0332: }
0333:
0334: /**
0335: * Creates a period from the given duration and end point.
0336: *
0337: * @param duration the duration of the interval, null means zero-length
0338: * @param endInstant the interval end, null means now
0339: * @param type which set of fields this period supports, null means standard
0340: */
0341: public MutablePeriod(ReadableDuration duration,
0342: ReadableInstant endInstant, PeriodType type) {
0343: super (duration, endInstant, type);
0344: }
0345:
0346: /**
0347: * Creates a period by converting or copying from another object.
0348: * <p>
0349: * The recognised object types are defined in
0350: * {@link org.joda.time.convert.ConverterManager ConverterManager} and
0351: * include ReadablePeriod, ReadableInterval and String.
0352: * The String formats are described by {@link ISOPeriodFormat#standard()}.
0353: *
0354: * @param period period to convert
0355: * @throws IllegalArgumentException if period is invalid
0356: * @throws UnsupportedOperationException if an unsupported field's value is non-zero
0357: */
0358: public MutablePeriod(Object period) {
0359: super (period, null, null);
0360: }
0361:
0362: /**
0363: * Creates a period by converting or copying from another object.
0364: * <p>
0365: * The recognised object types are defined in
0366: * {@link org.joda.time.convert.ConverterManager ConverterManager} and
0367: * include ReadablePeriod, ReadableInterval and String.
0368: * The String formats are described by {@link ISOPeriodFormat#standard()}.
0369: *
0370: * @param period period to convert
0371: * @param type which set of fields this period supports, null means use converter
0372: * @throws IllegalArgumentException if period is invalid
0373: * @throws UnsupportedOperationException if an unsupported field's value is non-zero
0374: */
0375: public MutablePeriod(Object period, PeriodType type) {
0376: super (period, type, null);
0377: }
0378:
0379: /**
0380: * Creates a period by converting or copying from another object.
0381: * <p>
0382: * The recognised object types are defined in
0383: * {@link org.joda.time.convert.ConverterManager ConverterManager} and
0384: * include ReadablePeriod, ReadableInterval and String.
0385: * The String formats are described by {@link ISOPeriodFormat#standard()}.
0386: *
0387: * @param period period to convert
0388: * @param chrono the chronology to use, null means ISO in default zone
0389: * @throws IllegalArgumentException if period is invalid
0390: * @throws UnsupportedOperationException if an unsupported field's value is non-zero
0391: */
0392: public MutablePeriod(Object period, Chronology chrono) {
0393: super (period, null, chrono);
0394: }
0395:
0396: /**
0397: * Creates a period by converting or copying from another object.
0398: * <p>
0399: * The recognised object types are defined in
0400: * {@link org.joda.time.convert.ConverterManager ConverterManager} and
0401: * include ReadablePeriod, ReadableInterval and String.
0402: * The String formats are described by {@link ISOPeriodFormat#standard()}.
0403: *
0404: * @param period period to convert
0405: * @param type which set of fields this period supports, null means use converter
0406: * @param chrono the chronology to use, null means ISO in default zone
0407: * @throws IllegalArgumentException if period is invalid
0408: * @throws UnsupportedOperationException if an unsupported field's value is non-zero
0409: */
0410: public MutablePeriod(Object period, PeriodType type,
0411: Chronology chrono) {
0412: super (period, type, chrono);
0413: }
0414:
0415: //-----------------------------------------------------------------------
0416: /**
0417: * Clears the period, setting all values back to zero.
0418: */
0419: public void clear() {
0420: super .setValues(new int[size()]);
0421: }
0422:
0423: /**
0424: * Sets the value of one of the fields by index.
0425: *
0426: * @param index the field index
0427: * @param value the new value for the field
0428: * @throws IndexOutOfBoundsException if the index is invalid
0429: */
0430: public void setValue(int index, int value) {
0431: super .setValue(index, value);
0432: }
0433:
0434: /**
0435: * Sets the value of one of the fields.
0436: * <p>
0437: * The field type specified must be one of those that is supported by the period.
0438: *
0439: * @param field a DurationFieldType instance that is supported by this period, not null
0440: * @param value the new value for the field
0441: * @throws IllegalArgumentException if the field is null or not supported
0442: */
0443: public void set(DurationFieldType field, int value) {
0444: super .setField(field, value);
0445: }
0446:
0447: /**
0448: * Sets all the fields in one go from another ReadablePeriod.
0449: *
0450: * @param period the period to set, null means zero length period
0451: * @throws IllegalArgumentException if an unsupported field's value is non-zero
0452: */
0453: public void setPeriod(ReadablePeriod period) {
0454: super .setPeriod(period);
0455: }
0456:
0457: /**
0458: * Sets all the fields in one go.
0459: *
0460: * @param years amount of years in this period, which must be zero if unsupported
0461: * @param months amount of months in this period, which must be zero if unsupported
0462: * @param weeks amount of weeks in this period, which must be zero if unsupported
0463: * @param days amount of days in this period, which must be zero if unsupported
0464: * @param hours amount of hours in this period, which must be zero if unsupported
0465: * @param minutes amount of minutes in this period, which must be zero if unsupported
0466: * @param seconds amount of seconds in this period, which must be zero if unsupported
0467: * @param millis amount of milliseconds in this period, which must be zero if unsupported
0468: * @throws IllegalArgumentException if an unsupported field's value is non-zero
0469: */
0470: public void setPeriod(int years, int months, int weeks, int days,
0471: int hours, int minutes, int seconds, int millis) {
0472: super .setPeriod(years, months, weeks, days, hours, minutes,
0473: seconds, millis);
0474: }
0475:
0476: /**
0477: * Sets all the fields in one go from an interval using the ISO chronology
0478: * and dividing the fields using the period type.
0479: *
0480: * @param interval the interval to set, null means zero length
0481: * @throws ArithmeticException if the set exceeds the capacity of the period
0482: */
0483: public void setPeriod(ReadableInterval interval) {
0484: if (interval == null) {
0485: setPeriod(0L);
0486: } else {
0487: Chronology chrono = DateTimeUtils.getChronology(interval
0488: .getChronology());
0489: setPeriod(interval.getStartMillis(), interval
0490: .getEndMillis(), chrono);
0491: }
0492: }
0493:
0494: /**
0495: * Sets all the fields in one go from two instants representing an interval.
0496: * <p>
0497: * The chronology of the start instant is used, unless that is null when the
0498: * chronology of the end instant is used instead.
0499: *
0500: * @param start the start instant, null means now
0501: * @param end the end instant, null means now
0502: * @throws ArithmeticException if the set exceeds the capacity of the period
0503: */
0504: public void setPeriod(ReadableInstant start, ReadableInstant end) {
0505: if (start == end) {
0506: setPeriod(0L);
0507: } else {
0508: long startMillis = DateTimeUtils.getInstantMillis(start);
0509: long endMillis = DateTimeUtils.getInstantMillis(end);
0510: Chronology chrono = DateTimeUtils.getIntervalChronology(
0511: start, end);
0512: setPeriod(startMillis, endMillis, chrono);
0513: }
0514: }
0515:
0516: /**
0517: * Sets all the fields in one go from a millisecond interval using ISOChronology
0518: * and dividing the fields using the period type.
0519: *
0520: * @param startInstant interval start, in milliseconds
0521: * @param endInstant interval end, in milliseconds
0522: * @throws ArithmeticException if the set exceeds the capacity of the period
0523: */
0524: public void setPeriod(long startInstant, long endInstant) {
0525: setPeriod(startInstant, endInstant, null);
0526: }
0527:
0528: /**
0529: * Sets all the fields in one go from a millisecond interval.
0530: *
0531: * @param startInstant interval start, in milliseconds
0532: * @param endInstant interval end, in milliseconds
0533: * @param chrono the chronology to use, not null
0534: * @throws ArithmeticException if the set exceeds the capacity of the period
0535: */
0536: public void setPeriod(long startInstant, long endInstant,
0537: Chronology chrono) {
0538: chrono = DateTimeUtils.getChronology(chrono);
0539: setValues(chrono.get(this , startInstant, endInstant));
0540: }
0541:
0542: /**
0543: * Sets all the fields in one go from a duration dividing the
0544: * fields using the period type.
0545: * <p>
0546: * When dividing the duration, only precise fields in the period type will be used.
0547: * For large durations, all the remaining duration will be stored in the largest
0548: * available precise field.
0549: *
0550: * @param duration the duration to set, null means zero length
0551: * @throws ArithmeticException if the set exceeds the capacity of the period
0552: */
0553: public void setPeriod(ReadableDuration duration) {
0554: setPeriod(duration, null);
0555: }
0556:
0557: /**
0558: * Sets all the fields in one go from a duration dividing the
0559: * fields using the period type.
0560: * <p>
0561: * When dividing the duration, only precise fields in the period type will be used.
0562: * For large durations, all the remaining duration will be stored in the largest
0563: * available precise field.
0564: *
0565: * @param duration the duration to set, null means zero length
0566: * @param chrono the chronology to use, null means ISO default
0567: * @throws ArithmeticException if the set exceeds the capacity of the period
0568: */
0569: public void setPeriod(ReadableDuration duration, Chronology chrono) {
0570: long durationMillis = DateTimeUtils.getDurationMillis(duration);
0571: setPeriod(durationMillis, chrono);
0572: }
0573:
0574: /**
0575: * Sets all the fields in one go from a millisecond duration dividing the
0576: * fields using the period type.
0577: * <p>
0578: * When dividing the duration, only precise fields in the period type will be used.
0579: * For large durations, all the remaining duration will be stored in the largest
0580: * available precise field.
0581: *
0582: * @param duration the duration, in milliseconds
0583: * @throws ArithmeticException if the set exceeds the capacity of the period
0584: */
0585: public void setPeriod(long duration) {
0586: setPeriod(duration, null);
0587: }
0588:
0589: /**
0590: * Sets all the fields in one go from a millisecond duration.
0591: * <p>
0592: * When dividing the duration, only precise fields in the period type will be used.
0593: * For large durations, all the remaining duration will be stored in the largest
0594: * available precise field.
0595: *
0596: * @param duration the duration, in milliseconds
0597: * @param chrono the chronology to use, not null
0598: * @throws ArithmeticException if the set exceeds the capacity of the period
0599: */
0600: public void setPeriod(long duration, Chronology chrono) {
0601: chrono = DateTimeUtils.getChronology(chrono);
0602: setValues(chrono.get(this , duration));
0603: }
0604:
0605: //-----------------------------------------------------------------------
0606: /**
0607: * Adds to the value of one of the fields.
0608: * <p>
0609: * The field type specified must be one of those that is supported by the period.
0610: *
0611: * @param field a DurationFieldType instance that is supported by this period, not null
0612: * @param value the value to add to the field
0613: * @throws IllegalArgumentException if the field is null or not supported
0614: */
0615: public void add(DurationFieldType field, int value) {
0616: super .addField(field, value);
0617: }
0618:
0619: /**
0620: * Adds a period to this one by adding each field in turn.
0621: *
0622: * @param period the period to add, null means add nothing
0623: * @throws IllegalArgumentException if the period being added contains a field
0624: * not supported by this period
0625: * @throws ArithmeticException if the addition exceeds the capacity of the period
0626: */
0627: public void add(ReadablePeriod period) {
0628: super .addPeriod(period);
0629: }
0630:
0631: /**
0632: * Adds to each field of this period.
0633: *
0634: * @param years amount of years to add to this period, which must be zero if unsupported
0635: * @param months amount of months to add to this period, which must be zero if unsupported
0636: * @param weeks amount of weeks to add to this period, which must be zero if unsupported
0637: * @param days amount of days to add to this period, which must be zero if unsupported
0638: * @param hours amount of hours to add to this period, which must be zero if unsupported
0639: * @param minutes amount of minutes to add to this period, which must be zero if unsupported
0640: * @param seconds amount of seconds to add to this period, which must be zero if unsupported
0641: * @param millis amount of milliseconds to add to this period, which must be zero if unsupported
0642: * @throws IllegalArgumentException if the period being added contains a field
0643: * not supported by this period
0644: * @throws ArithmeticException if the addition exceeds the capacity of the period
0645: */
0646: public void add(int years, int months, int weeks, int days,
0647: int hours, int minutes, int seconds, int millis) {
0648: setPeriod(FieldUtils.safeAdd(getYears(), years), FieldUtils
0649: .safeAdd(getMonths(), months), FieldUtils.safeAdd(
0650: getWeeks(), weeks),
0651: FieldUtils.safeAdd(getDays(), days), FieldUtils
0652: .safeAdd(getHours(), hours), FieldUtils
0653: .safeAdd(getMinutes(), minutes), FieldUtils
0654: .safeAdd(getSeconds(), seconds), FieldUtils
0655: .safeAdd(getMillis(), millis));
0656: }
0657:
0658: /**
0659: * Adds an interval to this one by dividing the interval into
0660: * fields and calling {@link #add(ReadablePeriod)}.
0661: *
0662: * @param interval the interval to add, null means add nothing
0663: * @throws ArithmeticException if the addition exceeds the capacity of the period
0664: */
0665: public void add(ReadableInterval interval) {
0666: if (interval != null) {
0667: add(interval.toPeriod(getPeriodType()));
0668: }
0669: }
0670:
0671: /**
0672: * Adds a duration to this one by dividing the duration into
0673: * fields and calling {@link #add(ReadablePeriod)}.
0674: *
0675: * @param duration the duration to add, null means add nothing
0676: * @throws ArithmeticException if the addition exceeds the capacity of the period
0677: */
0678: public void add(ReadableDuration duration) {
0679: if (duration != null) {
0680: add(new Period(duration.getMillis(), getPeriodType()));
0681: }
0682: }
0683:
0684: /**
0685: * Adds a millisecond duration to this one by dividing the duration into
0686: * fields and calling {@link #add(ReadablePeriod)}.
0687: * <p>
0688: * When dividing the duration, only precise fields in the period type will be used.
0689: * For large durations, all the remaining duration will be stored in the largest
0690: * available precise field.
0691: *
0692: * @param duration the duration, in milliseconds
0693: * @throws ArithmeticException if the addition exceeds the capacity of the period
0694: */
0695: public void add(long duration) {
0696: add(new Period(duration, getPeriodType()));
0697: }
0698:
0699: /**
0700: * Adds a millisecond duration to this one by dividing the duration into
0701: * fields and calling {@link #add(ReadablePeriod)}.
0702: * <p>
0703: * When dividing the duration, only precise fields in the period type will be used.
0704: * For large durations, all the remaining duration will be stored in the largest
0705: * available precise field.
0706: *
0707: * @param duration the duration, in milliseconds
0708: * @param chrono the chronology to use, null means ISO default
0709: * @throws ArithmeticException if the addition exceeds the capacity of the period
0710: */
0711: public void add(long duration, Chronology chrono) {
0712: add(new Period(duration, getPeriodType(), chrono));
0713: }
0714:
0715: //-----------------------------------------------------------------------
0716: /**
0717: * Merges all the fields from the specified period into this one.
0718: * <p>
0719: * Fields that are not present in the specified period are left unaltered.
0720: *
0721: * @param period the period to set, null ignored
0722: * @throws IllegalArgumentException if an unsupported field's value is non-zero
0723: */
0724: public void mergePeriod(ReadablePeriod period) {
0725: super .mergePeriod(period);
0726: }
0727:
0728: //-----------------------------------------------------------------------
0729: /**
0730: * Gets the years field part of the period.
0731: *
0732: * @return the number of years in the period, zero if unsupported
0733: */
0734: public int getYears() {
0735: return getPeriodType().getIndexedField(this ,
0736: PeriodType.YEAR_INDEX);
0737: }
0738:
0739: /**
0740: * Gets the months field part of the period.
0741: *
0742: * @return the number of months in the period, zero if unsupported
0743: */
0744: public int getMonths() {
0745: return getPeriodType().getIndexedField(this ,
0746: PeriodType.MONTH_INDEX);
0747: }
0748:
0749: /**
0750: * Gets the weeks field part of the period.
0751: *
0752: * @return the number of weeks in the period, zero if unsupported
0753: */
0754: public int getWeeks() {
0755: return getPeriodType().getIndexedField(this ,
0756: PeriodType.WEEK_INDEX);
0757: }
0758:
0759: /**
0760: * Gets the days field part of the period.
0761: *
0762: * @return the number of days in the period, zero if unsupported
0763: */
0764: public int getDays() {
0765: return getPeriodType().getIndexedField(this ,
0766: PeriodType.DAY_INDEX);
0767: }
0768:
0769: //-----------------------------------------------------------------------
0770: /**
0771: * Gets the hours field part of the period.
0772: *
0773: * @return the number of hours in the period, zero if unsupported
0774: */
0775: public int getHours() {
0776: return getPeriodType().getIndexedField(this ,
0777: PeriodType.HOUR_INDEX);
0778: }
0779:
0780: /**
0781: * Gets the minutes field part of the period.
0782: *
0783: * @return the number of minutes in the period, zero if unsupported
0784: */
0785: public int getMinutes() {
0786: return getPeriodType().getIndexedField(this ,
0787: PeriodType.MINUTE_INDEX);
0788: }
0789:
0790: /**
0791: * Gets the seconds field part of the period.
0792: *
0793: * @return the number of seconds in the period, zero if unsupported
0794: */
0795: public int getSeconds() {
0796: return getPeriodType().getIndexedField(this ,
0797: PeriodType.SECOND_INDEX);
0798: }
0799:
0800: /**
0801: * Gets the millis field part of the period.
0802: *
0803: * @return the number of millis in the period, zero if unsupported
0804: */
0805: public int getMillis() {
0806: return getPeriodType().getIndexedField(this ,
0807: PeriodType.MILLI_INDEX);
0808: }
0809:
0810: //-----------------------------------------------------------------------
0811: /**
0812: * Sets the number of years of the period.
0813: *
0814: * @param years the number of years
0815: * @throws IllegalArgumentException if field is not supported and the value is non-zero
0816: */
0817: public void setYears(int years) {
0818: super .setField(DurationFieldType.years(), years);
0819: }
0820:
0821: /**
0822: * Adds the specified years to the number of years in the period.
0823: *
0824: * @param years the number of years
0825: * @throws IllegalArgumentException if field is not supported and the value is non-zero
0826: * @throws ArithmeticException if the addition exceeds the capacity of the period
0827: */
0828: public void addYears(int years) {
0829: super .addField(DurationFieldType.years(), years);
0830: }
0831:
0832: //-----------------------------------------------------------------------
0833: /**
0834: * Sets the number of months of the period.
0835: *
0836: * @param months the number of months
0837: * @throws IllegalArgumentException if field is not supported and the value is non-zero
0838: */
0839: public void setMonths(int months) {
0840: super .setField(DurationFieldType.months(), months);
0841: }
0842:
0843: /**
0844: * Adds the specified months to the number of months in the period.
0845: *
0846: * @param months the number of months
0847: * @throws IllegalArgumentException if field is not supported and the value is non-zero
0848: * @throws ArithmeticException if the addition exceeds the capacity of the period
0849: */
0850: public void addMonths(int months) {
0851: super .addField(DurationFieldType.months(), months);
0852: }
0853:
0854: //-----------------------------------------------------------------------
0855: /**
0856: * Sets the number of weeks of the period.
0857: *
0858: * @param weeks the number of weeks
0859: * @throws IllegalArgumentException if field is not supported and the value is non-zero
0860: */
0861: public void setWeeks(int weeks) {
0862: super .setField(DurationFieldType.weeks(), weeks);
0863: }
0864:
0865: /**
0866: * Adds the specified weeks to the number of weeks in the period.
0867: *
0868: * @param weeks the number of weeks
0869: * @throws IllegalArgumentException if field is not supported and the value is non-zero
0870: * @throws ArithmeticException if the addition exceeds the capacity of the period
0871: */
0872: public void addWeeks(int weeks) {
0873: super .addField(DurationFieldType.weeks(), weeks);
0874: }
0875:
0876: //-----------------------------------------------------------------------
0877: /**
0878: * Sets the number of days of the period.
0879: *
0880: * @param days the number of days
0881: * @throws IllegalArgumentException if field is not supported and the value is non-zero
0882: */
0883: public void setDays(int days) {
0884: super .setField(DurationFieldType.days(), days);
0885: }
0886:
0887: /**
0888: * Adds the specified days to the number of days in the period.
0889: *
0890: * @param days the number of days
0891: * @throws IllegalArgumentException if field is not supported and the value is non-zero
0892: * @throws ArithmeticException if the addition exceeds the capacity of the period
0893: */
0894: public void addDays(int days) {
0895: super .addField(DurationFieldType.days(), days);
0896: }
0897:
0898: //-----------------------------------------------------------------------
0899: /**
0900: * Sets the number of hours of the period.
0901: *
0902: * @param hours the number of hours
0903: * @throws IllegalArgumentException if field is not supported and the value is non-zero
0904: */
0905: public void setHours(int hours) {
0906: super .setField(DurationFieldType.hours(), hours);
0907: }
0908:
0909: /**
0910: * Adds the specified hours to the number of hours in the period.
0911: *
0912: * @param hours the number of hours
0913: * @throws IllegalArgumentException if field is not supported and the value is non-zero
0914: * @throws ArithmeticException if the addition exceeds the capacity of the period
0915: */
0916: public void addHours(int hours) {
0917: super .addField(DurationFieldType.hours(), hours);
0918: }
0919:
0920: //-----------------------------------------------------------------------
0921: /**
0922: * Sets the number of minutes of the period.
0923: *
0924: * @param minutes the number of minutes
0925: * @throws IllegalArgumentException if field is not supported and the value is non-zero
0926: */
0927: public void setMinutes(int minutes) {
0928: super .setField(DurationFieldType.minutes(), minutes);
0929: }
0930:
0931: /**
0932: * Adds the specified minutes to the number of minutes in the period.
0933: *
0934: * @param minutes the number of minutes
0935: * @throws IllegalArgumentException if field is not supported and the value is non-zero
0936: * @throws ArithmeticException if the addition exceeds the capacity of the period
0937: */
0938: public void addMinutes(int minutes) {
0939: super .addField(DurationFieldType.minutes(), minutes);
0940: }
0941:
0942: //-----------------------------------------------------------------------
0943: /**
0944: * Sets the number of seconds of the period.
0945: *
0946: * @param seconds the number of seconds
0947: * @throws IllegalArgumentException if field is not supported and the value is non-zero
0948: */
0949: public void setSeconds(int seconds) {
0950: super .setField(DurationFieldType.seconds(), seconds);
0951: }
0952:
0953: /**
0954: * Adds the specified seconds to the number of seconds in the period.
0955: *
0956: * @param seconds the number of seconds
0957: * @throws IllegalArgumentException if field is not supported and the value is non-zero
0958: * @throws ArithmeticException if the addition exceeds the capacity of the period
0959: */
0960: public void addSeconds(int seconds) {
0961: super .addField(DurationFieldType.seconds(), seconds);
0962: }
0963:
0964: //-----------------------------------------------------------------------
0965: /**
0966: * Sets the number of millis of the period.
0967: *
0968: * @param millis the number of millis
0969: * @throws IllegalArgumentException if field is not supported and the value is non-zero
0970: */
0971: public void setMillis(int millis) {
0972: super .setField(DurationFieldType.millis(), millis);
0973: }
0974:
0975: /**
0976: * Adds the specified millis to the number of millis in the period.
0977: *
0978: * @param millis the number of millis
0979: * @throws IllegalArgumentException if field is not supported and the value is non-zero
0980: * @throws ArithmeticException if the addition exceeds the capacity of the period
0981: */
0982: public void addMillis(int millis) {
0983: super .addField(DurationFieldType.millis(), millis);
0984: }
0985:
0986: // Misc
0987: //-----------------------------------------------------------------------
0988: /**
0989: * Clone this object without having to cast the returned object.
0990: *
0991: * @return a clone of the this object.
0992: */
0993: public MutablePeriod copy() {
0994: return (MutablePeriod) clone();
0995: }
0996:
0997: /**
0998: * Clone this object.
0999: *
1000: * @return a clone of this object.
1001: */
1002: public Object clone() {
1003: try {
1004: return super .clone();
1005: } catch (CloneNotSupportedException ex) {
1006: throw new InternalError("Clone error");
1007: }
1008: }
1009:
1010: }
|