001/*
002 *  Copyright 2001-2005,2008 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 */
016package org.joda.time;
017
018import java.io.Serializable;
019
020import org.joda.time.base.BaseDuration;
021import org.joda.time.field.FieldUtils;
022
023/**
024 * An immutable duration specifying a length of time in milliseconds.
025 * <p>
026 * A duration is defined by a fixed number of milliseconds.
027 * There is no concept of fields, such as days or seconds, as these fields can vary in length.
028 * A duration may be converted to a {@link Period} to obtain field values.
029 * This conversion will typically cause a loss of precision however.
030 * <p>
031 * Duration is thread-safe and immutable.
032 *
033 * @author Brian S O'Neill
034 * @author Stephen Colebourne
035 * @since 1.0
036 */
037public final class Duration
038        extends BaseDuration
039        implements ReadableDuration, Serializable {
040
041    /** Constant representing zero millisecond duration */
042    public static final Duration ZERO = new Duration(0L);
043
044    /** Serialization version */
045    private static final long serialVersionUID = 2471658376918L;
046
047    //-----------------------------------------------------------------------
048    /**
049     * Create a duration with the specified number of days assuming that
050     * there are the standard number of milliseconds in a day.
051     * <p>
052     * This method assumes that there are 24 hours in a day,
053     * 60 minutes in an hour, 60 seconds in a minute and 1000 milliseconds in
054     * a second. This will be true for most days, however days with Daylight
055     * Savings changes will not have 24 hours, so use this method with care.
056     * <p>
057     * A Duration is a representation of an amount of time. If you want to express
058     * the concepts of 'days' you should consider using the {@link Days} class.
059     *
060     * @param days  the number of standard days in this duration
061     * @return the duration, never null
062     * @throws ArithmeticException if the days value is too large
063     * @since 1.6
064     */
065    public static Duration standardDays(long days) {
066        if (days == 0) {
067            return ZERO;
068        }
069        return new Duration(FieldUtils.safeMultiply(days, DateTimeConstants.MILLIS_PER_DAY));
070    }
071
072    /**
073     * Create a duration with the specified number of hours assuming that
074     * there are the standard number of milliseconds in an hour.
075     * <p>
076     * This method assumes that there are 60 minutes in an hour,
077     * 60 seconds in a minute and 1000 milliseconds in a second.
078     * All currently supplied chronologies use this definition.
079     * <p>
080     * A Duration is a representation of an amount of time. If you want to express
081     * the concepts of 'hours' you should consider using the {@link Hours} class.
082     *
083     * @param hours  the number of standard hours in this duration
084     * @return the duration, never null
085     * @throws ArithmeticException if the hours value is too large
086     * @since 1.6
087     */
088    public static Duration standardHours(long hours) {
089        if (hours == 0) {
090            return ZERO;
091        }
092        return new Duration(FieldUtils.safeMultiply(hours, DateTimeConstants.MILLIS_PER_HOUR));
093    }
094
095    /**
096     * Create a duration with the specified number of minutes assuming that
097     * there are the standard number of milliseconds in a minute.
098     * <p>
099     * This method assumes that there are 60 seconds in a minute and
100     * 1000 milliseconds in a second.
101     * All currently supplied chronologies use this definition.
102     * <p>
103     * A Duration is a representation of an amount of time. If you want to express
104     * the concepts of 'minutes' you should consider using the {@link Minutes} class.
105     *
106     * @param minutes  the number of standard minutes in this duration
107     * @return the duration, never null
108     * @throws ArithmeticException if the minutes value is too large
109     * @since 1.6
110     */
111    public static Duration standardMinutes(long minutes) {
112        if (minutes == 0) {
113            return ZERO;
114        }
115        return new Duration(FieldUtils.safeMultiply(minutes, DateTimeConstants.MILLIS_PER_MINUTE));
116    }
117
118    /**
119     * Create a duration with the specified number of seconds assuming that
120     * there are the standard number of milliseconds in a second.
121     * <p>
122     * This method assumes that there are 1000 milliseconds in a second.
123     * All currently supplied chronologies use this definition.
124     * <p>
125     * A Duration is a representation of an amount of time. If you want to express
126     * the concepts of 'seconds' you should consider using the {@link Seconds} class.
127     *
128     * @param seconds  the number of standard seconds in this duration
129     * @return the duration, never null
130     * @throws ArithmeticException if the seconds value is too large
131     * @since 1.6
132     */
133    public static Duration standardSeconds(long seconds) {
134        if (seconds == 0) {
135            return ZERO;
136        }
137        return new Duration(FieldUtils.safeMultiply(seconds, DateTimeConstants.MILLIS_PER_SECOND));
138    }
139
140    //-----------------------------------------------------------------------
141    /**
142     * Creates a duration from the given millisecond duration.
143     *
144     * @param duration  the duration, in milliseconds
145     */
146    public Duration(long duration) {
147        super(duration);
148    }
149
150    /**
151     * Creates a duration from the given interval endpoints.
152     *
153     * @param startInstant  interval start, in milliseconds
154     * @param endInstant  interval end, in milliseconds
155     * @throws ArithmeticException if the duration exceeds a 64 bit long
156     */
157    public Duration(long startInstant, long endInstant) {
158        super(startInstant, endInstant);
159    }
160
161    /**
162     * Creates a duration from the given interval endpoints.
163     *
164     * @param start  interval start, null means now
165     * @param end  interval end, null means now
166     * @throws ArithmeticException if the duration exceeds a 64 bit long
167     */
168    public Duration(ReadableInstant start, ReadableInstant end) {
169        super(start, end);
170    }
171
172    /**
173     * Creates a duration from the specified object using the
174     * {@link org.joda.time.convert.ConverterManager ConverterManager}.
175     *
176     * @param duration  duration to convert
177     * @throws IllegalArgumentException if duration is invalid
178     */
179    public Duration(Object duration) {
180        super(duration);
181    }
182
183    //-----------------------------------------------------------------------
184    /**
185     * Gets the length of this duration in seconds assuming 1000 milliseconds
186     * in a second.
187     * <p>
188     * This returns <code>getMillis() / 1000</code>.
189     * The result is an integer division, so 2999 millis returns 2 seconds.
190     *
191     * @return the length of the duration in standard seconds
192     * @since 1.6
193     */
194    public long getStandardSeconds() {
195        return getMillis() / DateTimeConstants.MILLIS_PER_SECOND;
196    }
197
198    //-----------------------------------------------------------------------
199    /**
200     * Get this duration as an immutable <code>Duration</code> object
201     * by returning <code>this</code>.
202     * 
203     * @return <code>this</code>
204     */
205    public Duration toDuration() {
206        return this;
207    }
208
209    /**
210     * Converts this duration to a period in seconds assuming 1000 milliseconds
211     * in a second.
212     * <p>
213     * This method allows you to convert between a duration and a period.
214     * 
215     * @return a period representing the number of standard seconds in this period, never null
216     * @throws ArithmeticException if the number of seconds is too large to be represented
217     * @since 1.6
218     */
219    public Seconds toStandardSeconds() {
220        long seconds = getStandardSeconds();
221        return Seconds.seconds(FieldUtils.safeToInt(seconds));
222    }
223
224    //-----------------------------------------------------------------------
225    /**
226     * Creates a new Duration instance with a different milisecond length.
227     * 
228     * @param duration  the new length of the duration
229     * @return the new duration instance
230     */
231    public Duration withMillis(long duration) {
232        if (duration == getMillis()) {
233            return this;
234        }
235        return new Duration(duration);
236    }
237
238    /**
239     * Returns a new duration with this length plus that specified multiplied by the scalar.
240     * This instance is immutable and is not altered.
241     * <p>
242     * If the addition is zero, this instance is returned.
243     * 
244     * @param durationToAdd  the duration to add to this one
245     * @param scalar  the amount of times to add, such as -1 to subtract once
246     * @return the new duration instance
247     */
248    public Duration withDurationAdded(long durationToAdd, int scalar) {
249        if (durationToAdd == 0 || scalar == 0) {
250            return this;
251        }
252        long add = FieldUtils.safeMultiply(durationToAdd, scalar);
253        long duration = FieldUtils.safeAdd(getMillis(), add);
254        return new Duration(duration);
255    }
256
257    /**
258     * Returns a new duration with this length plus that specified multiplied by the scalar.
259     * This instance is immutable and is not altered.
260     * <p>
261     * If the addition is zero, this instance is returned.
262     * 
263     * @param durationToAdd  the duration to add to this one, null means zero
264     * @param scalar  the amount of times to add, such as -1 to subtract once
265     * @return the new duration instance
266     */
267    public Duration withDurationAdded(ReadableDuration durationToAdd, int scalar) {
268        if (durationToAdd == null || scalar == 0) {
269            return this;
270        }
271        return withDurationAdded(durationToAdd.getMillis(), scalar);
272    }
273
274    //-----------------------------------------------------------------------
275    /**
276     * Returns a new duration with this length plus that specified.
277     * This instance is immutable and is not altered.
278     * <p>
279     * If the addition is zero, this instance is returned.
280     * 
281     * @param amount  the duration to add to this one
282     * @return the new duration instance
283     */
284    public Duration plus(long amount) {
285        return withDurationAdded(amount, 1);
286    }
287
288    /**
289     * Returns a new duration with this length plus that specified.
290     * This instance is immutable and is not altered.
291     * <p>
292     * If the amount is zero, this instance is returned.
293     * 
294     * @param amount  the duration to add to this one, null means zero
295     * @return the new duration instance
296     */
297    public Duration plus(ReadableDuration amount) {
298        if (amount == null) {
299            return this;
300        }
301        return withDurationAdded(amount.getMillis(), 1);
302    }
303
304    /**
305     * Returns a new duration with this length minus that specified.
306     * This instance is immutable and is not altered.
307     * <p>
308     * If the addition is zero, this instance is returned.
309     * 
310     * @param amount  the duration to take away from this one
311     * @return the new duration instance
312     */
313    public Duration minus(long amount) {
314        return withDurationAdded(amount, -1);
315    }
316
317    /**
318     * Returns a new duration with this length minus that specified.
319     * This instance is immutable and is not altered.
320     * <p>
321     * If the amount is zero, this instance is returned.
322     * 
323     * @param amount  the duration to take away from this one, null means zero
324     * @return the new duration instance
325     */
326    public Duration minus(ReadableDuration amount) {
327        if (amount == null) {
328            return this;
329        }
330        return withDurationAdded(amount.getMillis(), -1);
331    }
332
333}