286 }
287 return create(secs, nos);
288 }
289
290 //-----------------------------------------------------------------------
291 /**
292 * Obtains a {@code Duration} representing an amount in the specified unit.
293 * <p>
294 * The parameters represent the two parts of a phrase like '6 Hours'. For example:
295 * <pre>
296 * Duration.of(3, SECONDS);
297 * Duration.of(465, HOURS);
298 * </pre>
299 * Only a subset of units are accepted by this method.
300 * The unit must either have an {@linkplain TemporalUnit#isDurationEstimated() exact duration} or
301 * be {@link ChronoUnit#DAYS} which is treated as 24 hours. Other units throw an exception.
302 *
303 * @param amount the amount of the duration, measured in terms of the unit, positive or negative
304 * @param unit the unit that the duration is measured in, must have an exact duration, not null
305 * @return a {@code Duration}, not null
306 * @throws DateTimeException if the period unit has an estimated duration
307 * @throws ArithmeticException if a numeric overflow occurs
308 */
309 public static Duration of(long amount, TemporalUnit unit) {
310 return ZERO.plus(amount, unit);
311 }
312
313 //-----------------------------------------------------------------------
314 /**
315 * Obtains an instance of {@code Duration} from a temporal amount.
316 * <p>
317 * This obtains a duration based on the specified amount.
318 * A {@code TemporalAmount} represents an amount of time, which may be
319 * date-based or time-based, which this factory extracts to a duration.
320 * <p>
321 * The conversion loops around the set of units from the amount and uses
322 * the {@linkplain TemporalUnit#getDuration() duration} of the unit to
323 * calculate the total {@code Duration}.
324 * Only a subset of units are accepted by this method. The unit must either
325 * have an {@linkplain TemporalUnit#isDurationEstimated() exact duration}
326 * or be {@link ChronoUnit#DAYS} which is treated as 24 hours.
333 */
334 public static Duration from(TemporalAmount amount) {
335 Objects.requireNonNull(amount, "amount");
336 Duration duration = ZERO;
337 for (TemporalUnit unit : amount.getUnits()) {
338 duration = duration.plus(amount.get(unit), unit);
339 }
340 return duration;
341 }
342
343 //-----------------------------------------------------------------------
344 /**
345 * Obtains a {@code Duration} from a text string such as {@code PnDTnHnMn.nS}.
346 * <p>
347 * This will parse a textual representation of a duration, including the
348 * string produced by {@code toString()}. The formats accepted are based
349 * on the ISO-8601 duration format {@code PnDTnHnMn.nS} with days
350 * considered to be exactly 24 hours.
351 * <p>
352 * The string starts with an optional sign, denoted by the ASCII negative
353 * or positive symbol. If negative, the whole period is negated.
354 * The ASCII letter "P" is next in upper or lower case.
355 * There are then four sections, each consisting of a number and a suffix.
356 * The sections have suffixes in ASCII of "D", "H", "M" and "S" for
357 * days, hours, minutes and seconds, accepted in upper or lower case.
358 * The suffixes must occur in order. The ASCII letter "T" must occur before
359 * the first occurrence, if any, of an hour, minute or second section.
360 * At least one of the four sections must be present, and if "T" is present
361 * there must be at least one section after the "T".
362 * The number part of each section must consist of one or more ASCII digits.
363 * The number may be prefixed by the ASCII negative or positive symbol.
364 * The number of days, hours and minutes must parse to a {@code long}.
365 * The number of seconds must parse to a {@code long} with optional fraction.
366 * The decimal point may be either a dot or a comma.
367 * The fractional part may have from zero to 9 digits.
368 * <p>
369 * The leading plus/minus sign, and negative values for other units are
370 * not part of the ISO-8601 standard.
371 * <p>
372 * Examples:
373 * <pre>
457 long seconds = Math.addExact(daysAsSecs, Math.addExact(hoursAsSecs, Math.addExact(minsAsSecs, secs)));
458 if (negate) {
459 return ofSeconds(seconds, nanos).negated();
460 }
461 return ofSeconds(seconds, nanos);
462 }
463
464 //-----------------------------------------------------------------------
465 /**
466 * Obtains a {@code Duration} representing the duration between two temporal objects.
467 * <p>
468 * This calculates the duration between two temporal objects. If the objects
469 * are of different types, then the duration is calculated based on the type
470 * of the first object. For example, if the first argument is a {@code LocalTime}
471 * then the second argument is converted to a {@code LocalTime}.
472 * <p>
473 * The specified temporal objects must support the {@link ChronoUnit#SECONDS SECONDS} unit.
474 * For full accuracy, either the {@link ChronoUnit#NANOS NANOS} unit or the
475 * {@link ChronoField#NANO_OF_SECOND NANO_OF_SECOND} field should be supported.
476 * <p>
477 * The result of this method can be a negative period if the end is before the start.
478 * To guarantee to obtain a positive duration call {@link #abs()} on the result.
479 *
480 * @param startInclusive the start instant, inclusive, not null
481 * @param endExclusive the end instant, exclusive, not null
482 * @return a {@code Duration}, not null
483 * @throws DateTimeException if the seconds between the temporals cannot be obtained
484 * @throws ArithmeticException if the calculation exceeds the capacity of {@code Duration}
485 */
486 public static Duration between(Temporal startInclusive, Temporal endExclusive) {
487 try {
488 return ofNanos(startInclusive.until(endExclusive, NANOS));
489 } catch (DateTimeException | ArithmeticException ex) {
490 long secs = startInclusive.until(endExclusive, SECONDS);
491 long nanos;
492 try {
493 nanos = endExclusive.getLong(NANO_OF_SECOND) - startInclusive.getLong(NANO_OF_SECOND);
494 if (secs > 0 && nanos < 0) {
495 secs++;
496 } else if (secs < 0 && nanos > 0) {
497 secs--;
636 * A {@code Duration} represents a directed distance between two points on the time-line.
637 * A negative duration is expressed by the negative sign of the seconds part.
638 * A duration of -1 nanosecond is stored as -1 seconds plus 999,999,999 nanoseconds.
639 *
640 * @return the nanoseconds within the second part of the length of the duration, from 0 to 999,999,999
641 */
642 public int getNano() {
643 return nanos;
644 }
645
646 //-----------------------------------------------------------------------
647 /**
648 * Returns a copy of this duration with the specified amount of seconds.
649 * <p>
650 * This returns a duration with the specified seconds, retaining the
651 * nano-of-second part of this duration.
652 * <p>
653 * This instance is immutable and unaffected by this method call.
654 *
655 * @param seconds the seconds to represent, may be negative
656 * @return a {@code Duration} based on this period with the requested seconds, not null
657 */
658 public Duration withSeconds(long seconds) {
659 return create(seconds, nanos);
660 }
661
662 /**
663 * Returns a copy of this duration with the specified nano-of-second.
664 * <p>
665 * This returns a duration with the specified nano-of-second, retaining the
666 * seconds part of this duration.
667 * <p>
668 * This instance is immutable and unaffected by this method call.
669 *
670 * @param nanoOfSecond the nano-of-second to represent, from 0 to 999,999,999
671 * @return a {@code Duration} based on this period with the requested nano-of-second, not null
672 * @throws DateTimeException if the nano-of-second is invalid
673 */
674 public Duration withNanos(int nanoOfSecond) {
675 NANO_OF_SECOND.checkValidIntValue(nanoOfSecond);
676 return create(seconds, nanoOfSecond);
677 }
678
679 //-----------------------------------------------------------------------
680 /**
681 * Returns a copy of this duration with the specified duration added.
682 * <p>
683 * This instance is immutable and unaffected by this method call.
684 *
685 * @param duration the duration to add, positive or negative, not null
686 * @return a {@code Duration} based on this duration with the specified duration added, not null
687 * @throws ArithmeticException if numeric overflow occurs
688 */
689 public Duration plus(Duration duration) {
690 return plus(duration.getSeconds(), duration.getNano());
691 }
|
286 }
287 return create(secs, nos);
288 }
289
290 //-----------------------------------------------------------------------
291 /**
292 * Obtains a {@code Duration} representing an amount in the specified unit.
293 * <p>
294 * The parameters represent the two parts of a phrase like '6 Hours'. For example:
295 * <pre>
296 * Duration.of(3, SECONDS);
297 * Duration.of(465, HOURS);
298 * </pre>
299 * Only a subset of units are accepted by this method.
300 * The unit must either have an {@linkplain TemporalUnit#isDurationEstimated() exact duration} or
301 * be {@link ChronoUnit#DAYS} which is treated as 24 hours. Other units throw an exception.
302 *
303 * @param amount the amount of the duration, measured in terms of the unit, positive or negative
304 * @param unit the unit that the duration is measured in, must have an exact duration, not null
305 * @return a {@code Duration}, not null
306 * @throws DateTimeException if the unit has an estimated duration
307 * @throws ArithmeticException if a numeric overflow occurs
308 */
309 public static Duration of(long amount, TemporalUnit unit) {
310 return ZERO.plus(amount, unit);
311 }
312
313 //-----------------------------------------------------------------------
314 /**
315 * Obtains an instance of {@code Duration} from a temporal amount.
316 * <p>
317 * This obtains a duration based on the specified amount.
318 * A {@code TemporalAmount} represents an amount of time, which may be
319 * date-based or time-based, which this factory extracts to a duration.
320 * <p>
321 * The conversion loops around the set of units from the amount and uses
322 * the {@linkplain TemporalUnit#getDuration() duration} of the unit to
323 * calculate the total {@code Duration}.
324 * Only a subset of units are accepted by this method. The unit must either
325 * have an {@linkplain TemporalUnit#isDurationEstimated() exact duration}
326 * or be {@link ChronoUnit#DAYS} which is treated as 24 hours.
333 */
334 public static Duration from(TemporalAmount amount) {
335 Objects.requireNonNull(amount, "amount");
336 Duration duration = ZERO;
337 for (TemporalUnit unit : amount.getUnits()) {
338 duration = duration.plus(amount.get(unit), unit);
339 }
340 return duration;
341 }
342
343 //-----------------------------------------------------------------------
344 /**
345 * Obtains a {@code Duration} from a text string such as {@code PnDTnHnMn.nS}.
346 * <p>
347 * This will parse a textual representation of a duration, including the
348 * string produced by {@code toString()}. The formats accepted are based
349 * on the ISO-8601 duration format {@code PnDTnHnMn.nS} with days
350 * considered to be exactly 24 hours.
351 * <p>
352 * The string starts with an optional sign, denoted by the ASCII negative
353 * or positive symbol. If negative, the whole duration is negated.
354 * The ASCII letter "P" is next in upper or lower case.
355 * There are then four sections, each consisting of a number and a suffix.
356 * The sections have suffixes in ASCII of "D", "H", "M" and "S" for
357 * days, hours, minutes and seconds, accepted in upper or lower case.
358 * The suffixes must occur in order. The ASCII letter "T" must occur before
359 * the first occurrence, if any, of an hour, minute or second section.
360 * At least one of the four sections must be present, and if "T" is present
361 * there must be at least one section after the "T".
362 * The number part of each section must consist of one or more ASCII digits.
363 * The number may be prefixed by the ASCII negative or positive symbol.
364 * The number of days, hours and minutes must parse to a {@code long}.
365 * The number of seconds must parse to a {@code long} with optional fraction.
366 * The decimal point may be either a dot or a comma.
367 * The fractional part may have from zero to 9 digits.
368 * <p>
369 * The leading plus/minus sign, and negative values for other units are
370 * not part of the ISO-8601 standard.
371 * <p>
372 * Examples:
373 * <pre>
457 long seconds = Math.addExact(daysAsSecs, Math.addExact(hoursAsSecs, Math.addExact(minsAsSecs, secs)));
458 if (negate) {
459 return ofSeconds(seconds, nanos).negated();
460 }
461 return ofSeconds(seconds, nanos);
462 }
463
464 //-----------------------------------------------------------------------
465 /**
466 * Obtains a {@code Duration} representing the duration between two temporal objects.
467 * <p>
468 * This calculates the duration between two temporal objects. If the objects
469 * are of different types, then the duration is calculated based on the type
470 * of the first object. For example, if the first argument is a {@code LocalTime}
471 * then the second argument is converted to a {@code LocalTime}.
472 * <p>
473 * The specified temporal objects must support the {@link ChronoUnit#SECONDS SECONDS} unit.
474 * For full accuracy, either the {@link ChronoUnit#NANOS NANOS} unit or the
475 * {@link ChronoField#NANO_OF_SECOND NANO_OF_SECOND} field should be supported.
476 * <p>
477 * The result of this method can be a negative duration if the end is before the start.
478 * To guarantee to obtain a positive duration call {@link #abs()} on the result.
479 *
480 * @param startInclusive the start instant, inclusive, not null
481 * @param endExclusive the end instant, exclusive, not null
482 * @return a {@code Duration}, not null
483 * @throws DateTimeException if the seconds between the temporals cannot be obtained
484 * @throws ArithmeticException if the calculation exceeds the capacity of {@code Duration}
485 */
486 public static Duration between(Temporal startInclusive, Temporal endExclusive) {
487 try {
488 return ofNanos(startInclusive.until(endExclusive, NANOS));
489 } catch (DateTimeException | ArithmeticException ex) {
490 long secs = startInclusive.until(endExclusive, SECONDS);
491 long nanos;
492 try {
493 nanos = endExclusive.getLong(NANO_OF_SECOND) - startInclusive.getLong(NANO_OF_SECOND);
494 if (secs > 0 && nanos < 0) {
495 secs++;
496 } else if (secs < 0 && nanos > 0) {
497 secs--;
636 * A {@code Duration} represents a directed distance between two points on the time-line.
637 * A negative duration is expressed by the negative sign of the seconds part.
638 * A duration of -1 nanosecond is stored as -1 seconds plus 999,999,999 nanoseconds.
639 *
640 * @return the nanoseconds within the second part of the length of the duration, from 0 to 999,999,999
641 */
642 public int getNano() {
643 return nanos;
644 }
645
646 //-----------------------------------------------------------------------
647 /**
648 * Returns a copy of this duration with the specified amount of seconds.
649 * <p>
650 * This returns a duration with the specified seconds, retaining the
651 * nano-of-second part of this duration.
652 * <p>
653 * This instance is immutable and unaffected by this method call.
654 *
655 * @param seconds the seconds to represent, may be negative
656 * @return a {@code Duration} based on this duration with the requested seconds, not null
657 */
658 public Duration withSeconds(long seconds) {
659 return create(seconds, nanos);
660 }
661
662 /**
663 * Returns a copy of this duration with the specified nano-of-second.
664 * <p>
665 * This returns a duration with the specified nano-of-second, retaining the
666 * seconds part of this duration.
667 * <p>
668 * This instance is immutable and unaffected by this method call.
669 *
670 * @param nanoOfSecond the nano-of-second to represent, from 0 to 999,999,999
671 * @return a {@code Duration} based on this duration with the requested nano-of-second, not null
672 * @throws DateTimeException if the nano-of-second is invalid
673 */
674 public Duration withNanos(int nanoOfSecond) {
675 NANO_OF_SECOND.checkValidIntValue(nanoOfSecond);
676 return create(seconds, nanoOfSecond);
677 }
678
679 //-----------------------------------------------------------------------
680 /**
681 * Returns a copy of this duration with the specified duration added.
682 * <p>
683 * This instance is immutable and unaffected by this method call.
684 *
685 * @param duration the duration to add, positive or negative, not null
686 * @return a {@code Duration} based on this duration with the specified duration added, not null
687 * @throws ArithmeticException if numeric overflow occurs
688 */
689 public Duration plus(Duration duration) {
690 return plus(duration.getSeconds(), duration.getNano());
691 }
|