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 }