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 */
016 package org.joda.time;
017
018 import java.io.Serializable;
019
020 import org.joda.time.base.BaseDuration;
021 import 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 */
037 public 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 }