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.base;
017:
018: import java.io.Serializable;
019:
020: import org.joda.time.Chronology;
021: import org.joda.time.DateTimeUtils;
022: import org.joda.time.Interval;
023: import org.joda.time.Period;
024: import org.joda.time.PeriodType;
025: import org.joda.time.ReadableDuration;
026: import org.joda.time.ReadableInstant;
027: import org.joda.time.convert.ConverterManager;
028: import org.joda.time.convert.DurationConverter;
029: import org.joda.time.field.FieldUtils;
030:
031: /**
032: * BaseDuration is an abstract implementation of ReadableDuration that stores
033: * data in a <code>long</code> duration milliseconds field.
034: * <p>
035: * This class should generally not be used directly by API users.
036: * The {@link ReadableDuration} interface should be used when different
037: * kinds of duration objects are to be referenced.
038: * <p>
039: * BaseDuration subclasses may be mutable and not thread-safe.
040: *
041: * @author Brian S O'Neill
042: * @author Stephen Colebourne
043: * @since 1.0
044: */
045: public abstract class BaseDuration extends AbstractDuration implements
046: ReadableDuration, Serializable {
047:
048: /** Serialization version */
049: private static final long serialVersionUID = 2581698638990L;
050:
051: /** The duration length */
052: private long iMillis;
053:
054: /**
055: * Creates a duration from the given millisecond duration.
056: *
057: * @param duration the duration, in milliseconds
058: */
059: protected BaseDuration(long duration) {
060: super ();
061: iMillis = duration;
062: }
063:
064: /**
065: * Creates a duration from the given interval endpoints.
066: *
067: * @param startInstant interval start, in milliseconds
068: * @param endInstant interval end, in milliseconds
069: * @throws ArithmeticException if the duration exceeds a 64 bit long
070: */
071: protected BaseDuration(long startInstant, long endInstant) {
072: super ();
073: iMillis = FieldUtils.safeAdd(endInstant, -startInstant);
074: }
075:
076: /**
077: * Creates a duration from the given interval endpoints.
078: *
079: * @param start interval start, null means now
080: * @param end interval end, null means now
081: * @throws ArithmeticException if the duration exceeds a 64 bit long
082: */
083: protected BaseDuration(ReadableInstant start, ReadableInstant end) {
084: super ();
085: if (start == end) {
086: iMillis = 0L;
087: } else {
088: long startMillis = DateTimeUtils.getInstantMillis(start);
089: long endMillis = DateTimeUtils.getInstantMillis(end);
090: iMillis = FieldUtils.safeAdd(endMillis, -startMillis);
091: }
092: }
093:
094: /**
095: * Creates a duration from the specified object using the
096: * {@link org.joda.time.convert.ConverterManager ConverterManager}.
097: *
098: * @param duration duration to convert
099: * @throws IllegalArgumentException if duration is invalid
100: */
101: protected BaseDuration(Object duration) {
102: super ();
103: DurationConverter converter = ConverterManager.getInstance()
104: .getDurationConverter(duration);
105: iMillis = converter.getDurationMillis(duration);
106: }
107:
108: //-----------------------------------------------------------------------
109: /**
110: * Gets the length of this duration in milliseconds.
111: *
112: * @return the length of the duration in milliseconds.
113: */
114: public long getMillis() {
115: return iMillis;
116: }
117:
118: //-----------------------------------------------------------------------
119: /**
120: * Sets the length of this duration in milliseconds.
121: *
122: * @param duration the new length of the duration
123: */
124: protected void setMillis(long duration) {
125: iMillis = duration;
126: }
127:
128: //-----------------------------------------------------------------------
129: /**
130: * Converts this duration to a Period instance using the specified period type
131: * and the ISO chronology.
132: * <p>
133: * Only precise fields in the period type will be used.
134: * At most these are hours, minutes, seconds and millis - the period
135: * type may restrict the selection further.
136: * <p>
137: * For more control over the conversion process, you must pair the duration with
138: * an instant, see {@link #toPeriodFrom(ReadableInstant, PeriodType)}.
139: *
140: * @param type the period type to use, null means standard
141: * @return a Period created using the millisecond duration from this instance
142: */
143: public Period toPeriod(PeriodType type) {
144: return new Period(getMillis(), type);
145: }
146:
147: /**
148: * Converts this duration to a Period instance using the standard period type
149: * and the specified chronology.
150: * <p>
151: * Only precise fields in the period type will be used.
152: * Exactly which fields are precise depends on the chronology.
153: * Only the time fields are precise for ISO chronology with a time zone.
154: * However, ISO UTC also has precise days and weeks.
155: * <p>
156: * For more control over the conversion process, you must pair the duration with
157: * an instant, see {@link #toPeriodFrom(ReadableInstant)} and
158: * {@link #toPeriodTo(ReadableInstant)}
159: *
160: * @param chrono the chronology to use, null means ISO default
161: * @return a Period created using the millisecond duration from this instance
162: */
163: public Period toPeriod(Chronology chrono) {
164: return new Period(getMillis(), chrono);
165: }
166:
167: /**
168: * Converts this duration to a Period instance using the specified period type
169: * and chronology.
170: * <p>
171: * Only precise fields in the period type will be used.
172: * Exactly which fields are precise depends on the chronology.
173: * Only the time fields are precise for ISO chronology with a time zone.
174: * However, ISO UTC also has precise days and weeks.
175: * <p>
176: * For more control over the conversion process, you must pair the duration with
177: * an instant, see {@link #toPeriodFrom(ReadableInstant, PeriodType)} and
178: * {@link #toPeriodTo(ReadableInstant, PeriodType)}
179: *
180: * @param type the period type to use, null means standard
181: * @param chrono the chronology to use, null means ISO default
182: * @return a Period created using the millisecond duration from this instance
183: */
184: public Period toPeriod(PeriodType type, Chronology chrono) {
185: return new Period(getMillis(), type, chrono);
186: }
187:
188: /**
189: * Converts this duration to a Period instance by adding the duration to a start
190: * instant to obtain an interval using the standard period type.
191: * <p>
192: * This conversion will determine the fields of a period accurately.
193: * The results are based on the instant millis, the chronology of the instant,
194: * the standard period type and the length of this duration.
195: *
196: * @param startInstant the instant to calculate the period from, null means now
197: * @return a Period created using the millisecond duration from this instance
198: */
199: public Period toPeriodFrom(ReadableInstant startInstant) {
200: return new Period(startInstant, this );
201: }
202:
203: /**
204: * Converts this duration to a Period instance by adding the duration to a start
205: * instant to obtain an interval.
206: * <p>
207: * This conversion will determine the fields of a period accurately.
208: * The results are based on the instant millis, the chronology of the instant,
209: * the period type and the length of this duration.
210: *
211: * @param startInstant the instant to calculate the period from, null means now
212: * @param type the period type determining how to split the duration into fields, null means All type
213: * @return a Period created using the millisecond duration from this instance
214: */
215: public Period toPeriodFrom(ReadableInstant startInstant,
216: PeriodType type) {
217: return new Period(startInstant, this , type);
218: }
219:
220: /**
221: * Converts this duration to a Period instance by subtracting the duration
222: * from an end instant to obtain an interval using the standard period
223: * type.
224: * <p>
225: * This conversion will determine the fields of a period accurately.
226: * The results are based on the instant millis, the chronology of the instant,
227: * the standard period type and the length of this duration.
228: *
229: * @param endInstant the instant to calculate the period to, null means now
230: * @return a Period created using the millisecond duration from this instance
231: */
232: public Period toPeriodTo(ReadableInstant endInstant) {
233: return new Period(this , endInstant);
234: }
235:
236: /**
237: * Converts this duration to a Period instance by subtracting the duration
238: * from an end instant to obtain an interval using the standard period
239: * type.
240: * <p>
241: * This conversion will determine the fields of a period accurately.
242: * The results are based on the instant millis, the chronology of the instant,
243: * the period type and the length of this duration.
244: *
245: * @param endInstant the instant to calculate the period to, null means now
246: * @param type the period type determining how to split the duration into fields, null means All type
247: * @return a Period created using the millisecond duration from this instance
248: */
249: public Period toPeriodTo(ReadableInstant endInstant, PeriodType type) {
250: return new Period(this , endInstant, type);
251: }
252:
253: /**
254: * Converts this duration to an Interval starting at the specified instant.
255: *
256: * @param startInstant the instant to start the interval at, null means now
257: * @return an Interval starting at the specified instant
258: */
259: public Interval toIntervalFrom(ReadableInstant startInstant) {
260: return new Interval(startInstant, this );
261: }
262:
263: /**
264: * Converts this duration to an Interval ending at the specified instant.
265: *
266: * @param endInstant the instant to end the interval at, null means now
267: * @return an Interval ending at the specified instant
268: */
269: public Interval toIntervalTo(ReadableInstant endInstant) {
270: return new Interval(this, endInstant);
271: }
272:
273: }
|