View Javadoc

1   /*
2    *  Copyright 2001-2011 Stephen Colebourne
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  package org.joda.time.base;
17  
18  import java.io.Serializable;
19  
20  import org.joda.time.Chronology;
21  import org.joda.time.DateTimeUtils;
22  import org.joda.time.Interval;
23  import org.joda.time.Period;
24  import org.joda.time.PeriodType;
25  import org.joda.time.ReadableDuration;
26  import org.joda.time.ReadableInstant;
27  import org.joda.time.convert.ConverterManager;
28  import org.joda.time.convert.DurationConverter;
29  import org.joda.time.field.FieldUtils;
30  
31  /**
32   * BaseDuration is an abstract implementation of ReadableDuration that stores
33   * data in a <code>long</code> duration milliseconds field.
34   * <p>
35   * This class should generally not be used directly by API users.
36   * The {@link ReadableDuration} interface should be used when different 
37   * kinds of duration objects are to be referenced.
38   * <p>
39   * BaseDuration subclasses may be mutable and not thread-safe.
40   *
41   * @author Brian S O'Neill
42   * @author Stephen Colebourne
43   * @since 1.0
44   */
45  public abstract class BaseDuration
46          extends AbstractDuration
47          implements ReadableDuration, Serializable {
48  
49      /** Serialization version */
50      private static final long serialVersionUID = 2581698638990L;
51  
52      /** The duration length */
53      private volatile long iMillis;
54  
55      /**
56       * Creates a duration from the given millisecond duration.
57       *
58       * @param duration  the duration, in milliseconds
59       */
60      protected BaseDuration(long duration) {
61          super();
62          iMillis = duration;
63      }
64  
65      /**
66       * Creates a duration from the given interval endpoints.
67       *
68       * @param startInstant  interval start, in milliseconds
69       * @param endInstant  interval end, in milliseconds
70       * @throws ArithmeticException if the duration exceeds a 64 bit long
71       */
72      protected BaseDuration(long startInstant, long endInstant) {
73          super();
74          iMillis = FieldUtils.safeAdd(endInstant, -startInstant);
75      }
76  
77      /**
78       * Creates a duration from the given interval endpoints.
79       *
80       * @param start  interval start, null means now
81       * @param end  interval end, null means now
82       * @throws ArithmeticException if the duration exceeds a 64 bit long
83       */
84      protected BaseDuration(ReadableInstant start, ReadableInstant end) {
85          super();
86          if (start == end) {
87              iMillis = 0L;
88          } else {
89              long startMillis = DateTimeUtils.getInstantMillis(start);
90              long endMillis = DateTimeUtils.getInstantMillis(end);
91              iMillis = FieldUtils.safeAdd(endMillis, -startMillis);
92          }
93      }
94  
95      /**
96       * Creates a duration from the specified object using the
97       * {@link org.joda.time.convert.ConverterManager ConverterManager}.
98       *
99       * @param duration  duration to convert
100      * @throws IllegalArgumentException if duration is invalid
101      */
102     protected BaseDuration(Object duration) {
103         super();
104         DurationConverter converter = ConverterManager.getInstance().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, PeriodType type) {
216         return new Period(startInstant, this, type);
217     }
218 
219     /**
220      * Converts this duration to a Period instance by subtracting the duration
221      * from an end instant to obtain an interval using the standard period
222      * type.
223      * <p>
224      * This conversion will determine the fields of a period accurately.
225      * The results are based on the instant millis, the chronology of the instant,
226      * the standard period type and the length of this duration.
227      * 
228      * @param endInstant  the instant to calculate the period to, null means now
229      * @return a Period created using the millisecond duration from this instance
230      */
231     public Period toPeriodTo(ReadableInstant endInstant) {
232         return new Period(this, endInstant);
233     }
234 
235     /**
236      * Converts this duration to a Period instance by subtracting the duration
237      * from an end instant to obtain an interval using the standard period
238      * type.
239      * <p>
240      * This conversion will determine the fields of a period accurately.
241      * The results are based on the instant millis, the chronology of the instant,
242      * the period type and the length of this duration.
243      * 
244      * @param endInstant  the instant to calculate the period to, null means now
245      * @param type  the period type determining how to split the duration into fields, null means All type
246      * @return a Period created using the millisecond duration from this instance
247      */
248     public Period toPeriodTo(ReadableInstant endInstant, PeriodType type) {
249         return new Period(this, endInstant, type);
250     }
251 
252     /**
253      * Converts this duration to an Interval starting at the specified instant.
254      * 
255      * @param startInstant  the instant to start the interval at, null means now
256      * @return an Interval starting at the specified instant
257      */
258     public Interval toIntervalFrom(ReadableInstant startInstant) {
259         return new Interval(startInstant, this);
260     }
261 
262     /**
263      * Converts this duration to an Interval ending at the specified instant.
264      * 
265      * @param endInstant  the instant to end the interval at, null means now
266      * @return an Interval ending at the specified instant
267      */
268     public Interval toIntervalTo(ReadableInstant endInstant) {
269         return new Interval(this, endInstant);
270     }
271 
272 }