View Javadoc

1   /*
2    *  Copyright 2001-2010 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;
17  
18  import java.io.Serializable;
19  
20  import org.joda.convert.FromString;
21  import org.joda.time.base.BaseDuration;
22  import org.joda.time.field.FieldUtils;
23  
24  /**
25   * An immutable duration specifying a length of time in milliseconds.
26   * <p>
27   * A duration is defined by a fixed number of milliseconds.
28   * There is no concept of fields, such as days or seconds, as these fields can vary in length.
29   * A duration may be converted to a {@link Period} to obtain field values.
30   * This conversion will typically cause a loss of precision however.
31   * <p>
32   * Duration is thread-safe and immutable.
33   *
34   * @author Brian S O'Neill
35   * @author Stephen Colebourne
36   * @since 1.0
37   */
38  public final class Duration
39          extends BaseDuration
40          implements ReadableDuration, Serializable {
41  
42      /** Constant representing zero millisecond duration */
43      public static final Duration ZERO = new Duration(0L);
44  
45      /** Serialization version */
46      private static final long serialVersionUID = 2471658376918L;
47  
48      //-----------------------------------------------------------------------
49      /**
50       * Parses a {@code Duration} from the specified string.
51       * <p>
52       * This parses the format {@code PTa.bS}, as per {@link #toString()}.
53       * 
54       * @param str  the string to parse, not null
55       * @since 2.0
56       */
57      @FromString
58      public static Duration parse(String str) {
59          return new Duration(str);
60      }
61  
62      //-----------------------------------------------------------------------
63      /**
64       * Create a duration with the specified number of days assuming that
65       * there are the standard number of milliseconds in a day.
66       * <p>
67       * This method assumes that there are 24 hours in a day,
68       * 60 minutes in an hour, 60 seconds in a minute and 1000 milliseconds in
69       * a second. This will be true for most days, however days with Daylight
70       * Savings changes will not have 24 hours, so use this method with care.
71       * <p>
72       * A Duration is a representation of an amount of time. If you want to express
73       * the concepts of 'days' you should consider using the {@link Days} class.
74       *
75       * @param days  the number of standard days in this duration
76       * @return the duration, never null
77       * @throws ArithmeticException if the days value is too large
78       * @since 1.6
79       */
80      public static Duration standardDays(long days) {
81          if (days == 0) {
82              return ZERO;
83          }
84          return new Duration(FieldUtils.safeMultiply(days, DateTimeConstants.MILLIS_PER_DAY));
85      }
86  
87      /**
88       * Create a duration with the specified number of hours assuming that
89       * there are the standard number of milliseconds in an hour.
90       * <p>
91       * This method assumes that there are 60 minutes in an hour,
92       * 60 seconds in a minute and 1000 milliseconds in a second.
93       * All currently supplied chronologies use this definition.
94       * <p>
95       * A Duration is a representation of an amount of time. If you want to express
96       * the concepts of 'hours' you should consider using the {@link Hours} class.
97       *
98       * @param hours  the number of standard hours in this duration
99       * @return the duration, never null
100      * @throws ArithmeticException if the hours value is too large
101      * @since 1.6
102      */
103     public static Duration standardHours(long hours) {
104         if (hours == 0) {
105             return ZERO;
106         }
107         return new Duration(FieldUtils.safeMultiply(hours, DateTimeConstants.MILLIS_PER_HOUR));
108     }
109 
110     /**
111      * Create a duration with the specified number of minutes assuming that
112      * there are the standard number of milliseconds in a minute.
113      * <p>
114      * This method assumes that there are 60 seconds in a minute and
115      * 1000 milliseconds in a second.
116      * All currently supplied chronologies use this definition.
117      * <p>
118      * A Duration is a representation of an amount of time. If you want to express
119      * the concepts of 'minutes' you should consider using the {@link Minutes} class.
120      *
121      * @param minutes  the number of standard minutes in this duration
122      * @return the duration, never null
123      * @throws ArithmeticException if the minutes value is too large
124      * @since 1.6
125      */
126     public static Duration standardMinutes(long minutes) {
127         if (minutes == 0) {
128             return ZERO;
129         }
130         return new Duration(FieldUtils.safeMultiply(minutes, DateTimeConstants.MILLIS_PER_MINUTE));
131     }
132 
133     /**
134      * Create a duration with the specified number of seconds assuming that
135      * there are the standard number of milliseconds in a second.
136      * <p>
137      * This method assumes that there are 1000 milliseconds in a second.
138      * All currently supplied chronologies use this definition.
139      * <p>
140      * A Duration is a representation of an amount of time. If you want to express
141      * the concepts of 'seconds' you should consider using the {@link Seconds} class.
142      *
143      * @param seconds  the number of standard seconds in this duration
144      * @return the duration, never null
145      * @throws ArithmeticException if the seconds value is too large
146      * @since 1.6
147      */
148     public static Duration standardSeconds(long seconds) {
149         if (seconds == 0) {
150             return ZERO;
151         }
152         return new Duration(FieldUtils.safeMultiply(seconds, DateTimeConstants.MILLIS_PER_SECOND));
153     }
154 
155     /**
156      * Create a duration with the specified number of milliseconds.
157      *
158      * @param millis  the number of standard milliseconds in this duration
159      * @return the duration, never null
160      * @since 2.0
161      */
162     public static Duration millis(long millis) {
163         if (millis == 0) {
164             return ZERO;
165         }
166         return new Duration(millis);
167     }
168 
169     //-----------------------------------------------------------------------
170     /**
171      * Creates a duration from the given millisecond duration.
172      *
173      * @param duration  the duration, in milliseconds
174      */
175     public Duration(long duration) {
176         super(duration);
177     }
178 
179     /**
180      * Creates a duration from the given interval endpoints.
181      *
182      * @param startInstant  interval start, in milliseconds
183      * @param endInstant  interval end, in milliseconds
184      * @throws ArithmeticException if the duration exceeds a 64 bit long
185      */
186     public Duration(long startInstant, long endInstant) {
187         super(startInstant, endInstant);
188     }
189 
190     /**
191      * Creates a duration from the given interval endpoints.
192      *
193      * @param start  interval start, null means now
194      * @param end  interval end, null means now
195      * @throws ArithmeticException if the duration exceeds a 64 bit long
196      */
197     public Duration(ReadableInstant start, ReadableInstant end) {
198         super(start, end);
199     }
200 
201     /**
202      * Creates a duration from the specified object using the
203      * {@link org.joda.time.convert.ConverterManager ConverterManager}.
204      *
205      * @param duration  duration to convert
206      * @throws IllegalArgumentException if duration is invalid
207      */
208     public Duration(Object duration) {
209         super(duration);
210     }
211 
212     //-----------------------------------------------------------------------
213     /**
214      * Gets the length of this duration in days assuming that there are the
215      * standard number of milliseconds in a day.
216      * <p>
217      * This method assumes that there are 24 hours in a day,
218      * 60 minutes in an hour, 60 seconds in a minute and 1000 milliseconds in
219      * a second. This will be true for most days, however days with Daylight
220      * Savings changes will not have 24 hours, so use this method with care.
221      * <p>
222      * This returns <code>getMillis() / MILLIS_PER_DAY</code>.
223      * The result is an integer division, thus excess milliseconds are truncated.
224      *
225      * @return the length of the duration in standard seconds
226      * @since 2.0
227      */
228     public long getStandardDays() {
229         return getMillis() / DateTimeConstants.MILLIS_PER_DAY;
230     }
231 
232     /**
233      * Gets the length of this duration in hours assuming that there are the
234      * standard number of milliseconds in an hour.
235      * <p>
236      * This method assumes that there are 60 minutes in an hour,
237      * 60 seconds in a minute and 1000 milliseconds in a second.
238      * All currently supplied chronologies use this definition.
239      * <p>
240      * This returns <code>getMillis() / MILLIS_PER_HOUR</code>.
241      * The result is an integer division, thus excess milliseconds are truncated.
242      *
243      * @return the length of the duration in standard seconds
244      * @since 2.0
245      */
246     public long getStandardHours() {
247         return getMillis() / DateTimeConstants.MILLIS_PER_HOUR;
248     }
249 
250     /**
251      * Gets the length of this duration in minutes assuming that there are the
252      * standard number of milliseconds in a minute.
253      * <p>
254      * This method assumes that there are 60 seconds in a minute and
255      * 1000 milliseconds in a second.
256      * All currently supplied chronologies use this definition.
257      * <p>
258      * This returns <code>getMillis() / 60000</code>.
259      * The result is an integer division, thus excess milliseconds are truncated.
260      *
261      * @return the length of the duration in standard seconds
262      * @since 2.0
263      */
264     public long getStandardMinutes() {
265         return getMillis() / DateTimeConstants.MILLIS_PER_MINUTE;
266     }
267 
268     /**
269      * Gets the length of this duration in seconds assuming that there are the
270      * standard number of milliseconds in a second.
271      * <p>
272      * This method assumes that there are 1000 milliseconds in a second.
273      * All currently supplied chronologies use this definition.
274      * <p>
275      * This returns <code>getMillis() / 1000</code>.
276      * The result is an integer division, so 2999 millis returns 2 seconds.
277      *
278      * @return the length of the duration in standard seconds
279      * @since 1.6
280      */
281     public long getStandardSeconds() {
282         return getMillis() / DateTimeConstants.MILLIS_PER_SECOND;
283     }
284 
285     //-----------------------------------------------------------------------
286     /**
287      * Get this duration as an immutable <code>Duration</code> object
288      * by returning <code>this</code>.
289      * 
290      * @return <code>this</code>
291      */
292     public Duration toDuration() {
293         return this;
294     }
295 
296     /**
297      * Converts this duration to a period in days assuming that there are the
298      * standard number of milliseconds in a day.
299      * <p>
300      * This method assumes that there are 24 hours in a day,
301      * 60 minutes in an hour, 60 seconds in a minute and 1000 milliseconds in
302      * a second. This will be true for most days, however days with Daylight
303      * Savings changes will not have 24 hours, so use this method with care.
304      * 
305      * @return a period representing the number of standard days in this period, never null
306      * @throws ArithmeticException if the number of days is too large to be represented
307      * @since 2.0
308      */
309     public Days toStandardDays() {
310         long days = getStandardDays();
311         return Days.days(FieldUtils.safeToInt(days));
312     }
313 
314     /**
315      * Converts this duration to a period in hours assuming that there are the
316      * standard number of milliseconds in an hour.
317      * <p>
318      * This method assumes that there are 60 minutes in an hour,
319      * 60 seconds in a minute and 1000 milliseconds in a second.
320      * All currently supplied chronologies use this definition.
321      * 
322      * @return a period representing the number of standard hours in this period, never null
323      * @throws ArithmeticException if the number of hours is too large to be represented
324      * @since 2.0
325      */
326     public Hours toStandardHours() {
327         long hours = getStandardHours();
328         return Hours.hours(FieldUtils.safeToInt(hours));
329     }
330 
331     /**
332      * Converts this duration to a period in minutes assuming that there are the
333      * standard number of milliseconds in a minute.
334      * <p>
335      * This method assumes that there are 60 seconds in a minute and
336      * 1000 milliseconds in a second.
337      * All currently supplied chronologies use this definition.
338      * 
339      * @return a period representing the number of standard minutes in this period, never null
340      * @throws ArithmeticException if the number of minutes is too large to be represented
341      * @since 2.0
342      */
343     public Minutes toStandardMinutes() {
344         long minutes = getStandardMinutes();
345         return Minutes.minutes(FieldUtils.safeToInt(minutes));
346     }
347 
348     /**
349      * Converts this duration to a period in seconds assuming that there are the
350      * standard number of milliseconds in a second.
351      * <p>
352      * This method assumes that there are 1000 milliseconds in a second.
353      * All currently supplied chronologies use this definition.
354      * 
355      * @return a period representing the number of standard seconds in this period, never null
356      * @throws ArithmeticException if the number of seconds is too large to be represented
357      * @since 1.6
358      */
359     public Seconds toStandardSeconds() {
360         long seconds = getStandardSeconds();
361         return Seconds.seconds(FieldUtils.safeToInt(seconds));
362     }
363 
364     //-----------------------------------------------------------------------
365     /**
366      * Creates a new Duration instance with a different milisecond length.
367      * 
368      * @param duration  the new length of the duration
369      * @return the new duration instance
370      */
371     public Duration withMillis(long duration) {
372         if (duration == getMillis()) {
373             return this;
374         }
375         return new Duration(duration);
376     }
377 
378     /**
379      * Returns a new duration with this length plus that specified multiplied by the scalar.
380      * This instance is immutable and is not altered.
381      * <p>
382      * If the addition is zero, this instance is returned.
383      * 
384      * @param durationToAdd  the duration to add to this one
385      * @param scalar  the amount of times to add, such as -1 to subtract once
386      * @return the new duration instance
387      */
388     public Duration withDurationAdded(long durationToAdd, int scalar) {
389         if (durationToAdd == 0 || scalar == 0) {
390             return this;
391         }
392         long add = FieldUtils.safeMultiply(durationToAdd, scalar);
393         long duration = FieldUtils.safeAdd(getMillis(), add);
394         return new Duration(duration);
395     }
396 
397     /**
398      * Returns a new duration with this length plus that specified multiplied by the scalar.
399      * This instance is immutable and is not altered.
400      * <p>
401      * If the addition is zero, this instance is returned.
402      * 
403      * @param durationToAdd  the duration to add to this one, null means zero
404      * @param scalar  the amount of times to add, such as -1 to subtract once
405      * @return the new duration instance
406      */
407     public Duration withDurationAdded(ReadableDuration durationToAdd, int scalar) {
408         if (durationToAdd == null || scalar == 0) {
409             return this;
410         }
411         return withDurationAdded(durationToAdd.getMillis(), scalar);
412     }
413 
414     //-----------------------------------------------------------------------
415     /**
416      * Returns a new duration with this length plus that specified.
417      * This instance is immutable and is not altered.
418      * <p>
419      * If the addition is zero, this instance is returned.
420      * 
421      * @param amount  the duration to add to this one
422      * @return the new duration instance
423      */
424     public Duration plus(long amount) {
425         return withDurationAdded(amount, 1);
426     }
427 
428     /**
429      * Returns a new duration with this length plus that specified.
430      * This instance is immutable and is not altered.
431      * <p>
432      * If the amount is zero, this instance is returned.
433      * 
434      * @param amount  the duration to add to this one, null means zero
435      * @return the new duration instance
436      */
437     public Duration plus(ReadableDuration amount) {
438         if (amount == null) {
439             return this;
440         }
441         return withDurationAdded(amount.getMillis(), 1);
442     }
443 
444     /**
445      * Returns a new duration with this length minus that specified.
446      * This instance is immutable and is not altered.
447      * <p>
448      * If the addition is zero, this instance is returned.
449      * 
450      * @param amount  the duration to take away from this one
451      * @return the new duration instance
452      */
453     public Duration minus(long amount) {
454         return withDurationAdded(amount, -1);
455     }
456 
457     /**
458      * Returns a new duration with this length minus that specified.
459      * This instance is immutable and is not altered.
460      * <p>
461      * If the amount is zero, this instance is returned.
462      * 
463      * @param amount  the duration to take away from this one, null means zero
464      * @return the new duration instance
465      */
466     public Duration minus(ReadableDuration amount) {
467         if (amount == null) {
468             return this;
469         }
470         return withDurationAdded(amount.getMillis(), -1);
471     }
472 
473 }