001    /*
002     *  Copyright 2001-2010 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.convert.FromString;
021    import org.joda.time.base.BaseDuration;
022    import org.joda.time.field.FieldUtils;
023    
024    /**
025     * An immutable duration specifying a length of time in milliseconds.
026     * <p>
027     * A duration is defined by a fixed number of milliseconds.
028     * There is no concept of fields, such as days or seconds, as these fields can vary in length.
029     * A duration may be converted to a {@link Period} to obtain field values.
030     * This conversion will typically cause a loss of precision however.
031     * <p>
032     * Duration is thread-safe and immutable.
033     *
034     * @author Brian S O'Neill
035     * @author Stephen Colebourne
036     * @since 1.0
037     */
038    public final class Duration
039            extends BaseDuration
040            implements ReadableDuration, Serializable {
041    
042        /** Constant representing zero millisecond duration */
043        public static final Duration ZERO = new Duration(0L);
044    
045        /** Serialization version */
046        private static final long serialVersionUID = 2471658376918L;
047    
048        //-----------------------------------------------------------------------
049        /**
050         * Parses a {@code Duration} from the specified string.
051         * <p>
052         * This parses the format {@code PTa.bS}, as per {@link #toString()}.
053         * 
054         * @param str  the string to parse, not null
055         * @since 2.0
056         */
057        @FromString
058        public static Duration parse(String str) {
059            return new Duration(str);
060        }
061    
062        //-----------------------------------------------------------------------
063        /**
064         * Create a duration with the specified number of days assuming that
065         * there are the standard number of milliseconds in a day.
066         * <p>
067         * This method assumes that there are 24 hours in a day,
068         * 60 minutes in an hour, 60 seconds in a minute and 1000 milliseconds in
069         * a second. This will be true for most days, however days with Daylight
070         * Savings changes will not have 24 hours, so use this method with care.
071         * <p>
072         * A Duration is a representation of an amount of time. If you want to express
073         * the concepts of 'days' you should consider using the {@link Days} class.
074         *
075         * @param days  the number of standard days in this duration
076         * @return the duration, never null
077         * @throws ArithmeticException if the days value is too large
078         * @since 1.6
079         */
080        public static Duration standardDays(long days) {
081            if (days == 0) {
082                return ZERO;
083            }
084            return new Duration(FieldUtils.safeMultiply(days, DateTimeConstants.MILLIS_PER_DAY));
085        }
086    
087        /**
088         * Create a duration with the specified number of hours assuming that
089         * there are the standard number of milliseconds in an hour.
090         * <p>
091         * This method assumes that there are 60 minutes in an hour,
092         * 60 seconds in a minute and 1000 milliseconds in a second.
093         * All currently supplied chronologies use this definition.
094         * <p>
095         * A Duration is a representation of an amount of time. If you want to express
096         * the concepts of 'hours' you should consider using the {@link Hours} class.
097         *
098         * @param hours  the number of standard hours in this duration
099         * @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    }