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 }