Package net.time4j

Class Duration<U extends IsoUnit>

Type Parameters:
U - generic type of time units
All Implemented Interfaces:
Serializable, TimeSpan<U>

public final class Duration<U extends IsoUnit> extends AbstractDuration<U> implements Serializable

ISO-8601-compatible duration between two time points.

Instances can be created by following factory methods:

All instances are immutable, but changed copies can be created by using the methods plus(), with(), union(), multipliedBy(), abs() and inverse(). The time units ClockUnit.MILLIS and ClockUnit.MICROS will automatically normalized to nanoseconds. In every other case a normalization must be explicitly triggered by with(Normalizer).

Note: The definition of an optional negative sign is not part of ISO-8061, but part of the XML-schema-specification and defines the position of two time points relative to each other. A manipulation of the sign is possible with the method inverse().

The time arithmetic handles the addition of a duration to a time point and the subtraction of a duration from a time point as dependent on the sign of the duration as described in the standard algorithm of the super class.

Author:
Meno Hochschild
See Also:
Serialized Form
  • Field Details

    • STD_PERIOD

      public static Normalizer<IsoUnit> STD_PERIOD

      Normalizes the duration items on the base of 1 year = 12 months and 1 day = 24 hours and 1 hour = 60 minutes and 1 minute = 60 seconds - without converting days to months.

      Attention: Timezone-dependent changes of length of day or leapseconds are ignored. That is why this normalization should only be applied on ISO-timestamps without timezone reference. Only time units of enum types CalendarUnit and ClockUnit will be normalized.

      Weeks will be normalized to days if weeks do not represent the only calendrical duration items.

      See Also:
      PlainTimestamp.normalize(TimeSpan)
    • STD_CALENDAR_PERIOD

      public static Normalizer<CalendarUnit> STD_CALENDAR_PERIOD

      Normalizes the calendrical items of a duration on the base 1 year = 12 months - without converting the days to months.

      Weeks will be normalized to days if weeks do not represent the only calendrical duration items. Only time units of type CalendarUnit will be normalized.

      See Also:
      PlainDate.normalize(TimeSpan)
    • STD_CLOCK_PERIOD

      public static Normalizer<ClockUnit> STD_CLOCK_PERIOD

      Normalizes the wall time items of a duration on the base 1 day = 24 hours und 1 hour = 60 minutes and 1 minute = 60 seconds.

      Attention: Timezone-dependent changes of length of day or leapseconds are ignored. That is why this normalization should only be applied on ISO-timestamps without timezone reference. Only time units of enum type ClockUnit will be normalized.

      See Also:
      PlainTime
  • Method Details

    • ofZero

      public static <U extends IsoUnit> Duration<U> ofZero()

      Gets an empty duration without units.

      This method can also be used for generic upcasting of the type U to IsoUnit:

              Duration<CalendarUnit> dur = Duration.ofCalendarUnits(2, 5, 30);
              Duration<IsoUnit> upcasted = Duration.ofZero().plus(dur);
       
      Type Parameters:
      U - generic unit type
      Returns:
      empty duration
    • of

      public static <U extends IsoUnit> Duration<U> of(long amount, U unit)

      Creates a new duration which only knows one unit.

      Is the given amount is negative then the duration will be negative, too. Is the amount equal to 0 then an empty duration will be returned. Milliseconds or microseconds will be automatically normalized to nanoseconds.

      Type Parameters:
      U - generic unit type
      Parameters:
      amount - amount as count of units
      unit - single time unit
      Returns:
      new duration
    • ofPositive

      public static Duration.Builder ofPositive()

      Konstructs a new positive duration for combined date- and time items by applying the builder pattern.

      Returns:
      help object for building a positive Duration
    • ofNegative

      public static Duration.Builder ofNegative()

      Konstructs a new negative duration for combined date- and time items by applying the builder pattern.

      Returns:
      help object for building a negative Duration
    • ofCalendarUnits

      public static Duration<CalendarUnit> ofCalendarUnits(int years, int months, int days)

      Creates a positive duration in years, months and days.

      All arguments must not be negative. Is any argument equal to 0 then it will be ignored. If a negative duration is needed then an application can simply call inverse() on the result.

      Parameters:
      years - amount in years
      months - amount in months
      days - amount in days
      Returns:
      new duration
      Throws:
      IllegalArgumentException - if any argument is negative
      See Also:
      inverse()
    • ofClockUnits

      public static Duration<ClockUnit> ofClockUnits(int hours, int minutes, int seconds)

      Creates a positive duratioon in hours, minutes and seconds.

      All arguments must not be negative. Is any argument equal to 0 then it will be ignored. If a negative duration is needed then an application can simply call inverse() on the result.

      Parameters:
      hours - amount in hours
      minutes - amount in minutes
      seconds - amount in seconds
      Returns:
      new duration
      Throws:
      IllegalArgumentException - if any argument is negative
      See Also:
      inverse()
    • from

      public static Duration<IsoUnit> from(TemporalAmount threeten)

      Tries to convert given temporal amount to a duration.

      Note that the arithmetic of given amount is probably different from that of the result. Every unit compatible with java.time.temporal.ChronoUnit with exception of ERAS and FOREVER can be processed. Also the units IsoFields.QUARTER_YEARS and IsoFields.WEEK_BASED_YEARS are accepted.

      Parameters:
      threeten - temporal amount
      Returns:
      normalized duration
      Throws:
      IllegalArgumentException - if the argument contains a non-mappable temporal unit or has mixed signs
      Since:
      4.0
      See Also:
      from(java.time.Duration), from(java.time.Period), STD_PERIOD
    • from

      public static Duration<ClockUnit> from(Duration threetenDuration)

      Short cut for TemporalType.THREETEN_DURATION.translate(threetenDuration).

      Parameters:
      threetenDuration - Threeten-equivalent of a clock duration
      Returns:
      normalized clock duration
      Since:
      4.0
      See Also:
      TemporalType.THREETEN_DURATION, STD_CLOCK_PERIOD
    • from

      public static Duration<CalendarUnit> from(Period threetenPeriod)

      Short cut for TemporalType.THREETEN_PERIOD.translate(threetenPeriod).

      Note that the arithmetic of given period is slightly different from that of the result when it comes to handling negative durations:

           System.out.println(
             LocalDate.of(2015, 7, 1).minus(Period.of(0, 1, 1))); // 2015-05-31
           System.out.println(
             PlainDate.of(2015, 7, 1).minus(Duration.ofCalendarUnits(0, 1, 1))); // 2015-05-30
       
      Parameters:
      threetenPeriod - Threeten-equivalent of a calendar duration
      Returns:
      normalized calendar duration
      Throws:
      ChronoException - if conversion fails due to mixed signs
      Since:
      4.0
      See Also:
      TemporalType.THREETEN_PERIOD, STD_CALENDAR_PERIOD
    • in

      @SafeVarargs public static <U extends IsoUnit> TimeMetric<U,​Duration<U>> in(U... units)

      Constructs a metric for any kind of standard units in normalized form.

      Important: If the smallest unit is missing which fits the precision of timepoints to be compared then a remainder of subtraction will exist. The result of distance calculation will not express the full temporal distance in this case. For the completeness of calculation, the day unit is required if the distance between two dates is needed.

      Example with different unit types: If this method is called with different unit types then it is strongly recommended to first assign the units to static constants of type IsoUnit in order to avoid compiler problems with generics. This practice also helps to improve the readability of code.

        private static final IsoUnit DAYS = CalendarUnit.DAYS;
        private static final IsoUnit HOURS = ClockUnit.HOURS;
        private static final IsoUnit MINUTES = ClockUnit.MINUTES;
      
        PlainTimestamp start = PlainTimestamp.of(2014, 3, 28, 0, 30);
        PlainTimestamp end = PlainTimestamp.of(2014, 4, 5, 14, 15);
        Duration<IsoUnit> duration =
            Duration.in(DAYS, HOURS, MINUTES).between(start, end);
        System.out.println(duration); // output: P8DT13H45M
       
      Type Parameters:
      U - generic unit type
      Parameters:
      units - time units to be used in calculation
      Returns:
      reversible immutable metric for calculating a duration in given units
      Throws:
      IllegalArgumentException - if no time unit is given or if there are unit duplicates
      See Also:
      AbstractMetric
    • in

      public static <U extends IsoUnit> TimeMetric<U,​Duration<U>> in(Collection<? extends U> units)

      Constructs a metric for any kind of standard units in normalized form.

      Type Parameters:
      U - generic unit type
      Parameters:
      units - time units to be used in calculation
      Returns:
      reversible immutable metric for calculating a duration in given units
      Throws:
      IllegalArgumentException - if no time unit is given or if there are unit duplicates
      Since:
      5.6
      See Also:
      AbstractMetric, in(IsoUnit[])
    • inYearsMonthsDays

      public static TimeMetric<CalendarUnit,​Duration<CalendarUnit>> inYearsMonthsDays()

      Constructs a metric in years, months and days.

      Finally the resulting duration will be normalized such that smaller units will be converted to bigger units if possible.

      Returns:
      reversible immutable metric for calculating a duration in years, months and days
      See Also:
      in(U[]), CalendarUnit.YEARS, CalendarUnit.MONTHS, CalendarUnit.DAYS, AbstractMetric
    • inClockUnits

      public static TimeMetric<ClockUnit,​Duration<ClockUnit>> inClockUnits()

      Constructs a metric in hours, minutes, seconds and nanoseconds.

      Finally the resulting duration will be normalized such that smaller units will be converted to bigger units if possible.

      Returns:
      reversible immutable metric for calculating a duration in clock units
      See Also:
      in(U[]), ClockUnit.HOURS, ClockUnit.MINUTES, ClockUnit.SECONDS, ClockUnit.NANOS, AbstractMetric
    • inWeekBasedUnits

      public static TimeMetric<IsoDateUnit,​Duration<IsoDateUnit>> inWeekBasedUnits()

      Constructs a metric in week-based years, weeks and days.

      Finally the resulting duration will be normalized such that smaller units will be converted to bigger units if possible.

      Returns:
      reversible immutable metric for calculating a duration in week-based years, weeks and days
      Since:
      3.21/4.17
      See Also:
      in(U[]), CalendarUnit.weekBasedYears(), CalendarUnit.WEEKS, CalendarUnit.DAYS, AbstractMetric
    • in

      public static TimeMetric<IsoUnit,​Duration<IsoUnit>> in(Timezone tz, IsoUnit... units)

      Helps to evaluate the zonal duration between two timestamps and applies an offset correction if necessary.

      Following example handles the change from winter time to summer time in Germany causing 4 instead of 5 hours difference:

        PlainTimestamp start = PlainTimestamp.of(2014, 3, 30, 0, 0);
        PlainTimestamp end = PlainTimestamp.of(2014, 3, 30, 5, 0);
        IsoUnit hours = ClockUnit.HOURS;
        System.out.println(
            Duration.in(Timezone.of("Europe/Berlin"), hours)
                .between(start, end).toString()); // output: PT4H
       
      Parameters:
      tz - timezone
      units - time units to be used in calculation
      Returns:
      non-reversible zonal metric for calculating a duration in given units
      Throws:
      IllegalArgumentException - if no time unit is given or if there are unit duplicates
      Since:
      1.2
    • getTotalLength

      public List<TimeSpan.Item<U>> getTotalLength()
      Description copied from interface: TimeSpan

      Yields all containted time span items with amount and unit in the order from largest to smallest time units.

      Specified by:
      getTotalLength in interface TimeSpan<U extends IsoUnit>
      Returns:
      unmodifiable list sorted by precision of units in ascending order where every time unit exists at most once
    • isNegative

      public boolean isNegative()
      Description copied from interface: TimeSpan

      Queries if this time span is negative.

      A negative time span relates to the subtraction of two time points where first one is after second one. The partial amounts of every time span are never negative. Hence this attribute is not associated with the partial amounts but only with the time span itself.

      Note: An empty time span itself is never negative in agreement with the mathematical relation (-1) * 0 = 0.

      Specified by:
      isNegative in interface TimeSpan<U extends IsoUnit>
      Returns:
      true if negative and not empty else false
    • contains

      public boolean contains(IsoUnit unit)

      Queries if this duration contains given time unit.

      Any time unit is also part of this duration if it is a fractional part of a second (digit symbol) which is to be converted first.

      Specified by:
      contains in interface TimeSpan<U extends IsoUnit>
      Overrides:
      contains in class AbstractDuration<U extends IsoUnit>
      Parameters:
      unit - time unit to be checked (optional)
      Returns:
      true if this duration contains given unit else false
      See Also:
      getPartialAmount(U)
    • getPartialAmount

      public long getPartialAmount(IsoUnit unit)

      Gets the partial amount associated with given time unit.

      If this duration does not contain given time unit then this method will yield the value 0. Fractional parts of seconds which are known by their numerical symbols will automatically be converted. That means if a duration stores nanoseconds, but is queried for microseconds then the nanosecond amount will be multiplied by factor 1000 and finally returned.

      Specified by:
      getPartialAmount in interface TimeSpan<U extends IsoUnit>
      Overrides:
      getPartialAmount in class AbstractDuration<U extends IsoUnit>
      Parameters:
      unit - time unit the amount is queried for (optional)
      Returns:
      non-negative amount associated with given unit (>= 0)
    • comparator

      public static <U extends IsoUnit,​ T extends TimePoint<U,​ T>> Comparator<Duration<? extends U>> comparator(T base)

      Creates a Comparator which compares durations based on their lengths.

      Internally, the comparing algorithm uses the expression base.plus(duration1).compareTo(base.plus(duration2)). The given basis time point is necessary because some durations with flexible units like months have else no fixed length.

      Type Parameters:
      U - generic unit type
      T - generic type of time point
      Parameters:
      base - base time point which durations will use for comparison
      Returns:
      Comparator for plain durations
      See Also:
      TimePoint.compareTo(T)
    • comparatorOnClock

      public static Comparator<Duration<ClockUnit>> comparatorOnClock()

      Obtains a comparator suitable for Durations based on clock units.

      A negative duration is always smaller than a positive one. Example:

           Duration<ClockUnit> d1 = Duration.parseClockPeriod("PT22M2.666S");
           Duration<ClockUnit> d2 = Duration.parseClockPeriod("-PT25M");
           Duration<ClockUnit> d3 = Duration.parseClockPeriod("PT21M62.667S");
           Duration<ClockUnit> d4 = Duration.parseClockPeriod("PT22M2.667S");
           Stream<Duration<ClockUnit>> s = Stream.of(d1, d2, d3, d4);
           assertThat(s.max(Duration.comparatorOnClock()).get(), is(d3));
       
      Returns:
      Comparator for clock-based durations
      Since:
      5.0
    • plus

      public Duration<U> plus(long amount, U unit)

      Gets a copy of this duration where given amount will be added to the partial amount of this duration in given unit.

      The method also takes in account the sign of the duration. Example:

        System.out.println(Duration.of(5, MONTHS).plus(-6, MONTHS));
        // output: -P1M
       

      Notes: Is the amount to be added equal to 0 then the method will simply yield this duration. Mixed signs are not permitted and will be rejected by an exception. For example following expression is not allowed:

        Duration.of(-1, MONTHS).plus(30, DAYS); // throws IllegalStateException
       
      Parameters:
      amount - temporal amount to be added (maybe negative)
      unit - associated time unit
      Returns:
      new changed duration while this duration remains unaffected
      Throws:
      IllegalStateException - if the result gets mixed signs by adding the partial amounts
      IllegalArgumentException - if different units of same length exist
      ArithmeticException - in case of long overflow
      See Also:
      with(long, U)
    • plus

      public Duration<U> plus(TimeSpan<? extends U> timespan)

      Creates a duration as union of this instance and given timespan where partial amounts of equal units will be summed up.

      In order to sum up timespans with different unit types, following trick can be applied:

        Duration<IsoUnit> zero = Duration.ofZero();
        Duration<IsoUnit> result = zero.plus(this).plus(timespan);
       

      Note about sign handling: If this duration and given timespan have different signs then Time4J tries to apply a normalization in the hope the mixed signs disappear. Otherwise this method will throw an exception in case of mixed signs for different duration items. So it is strongly recommended only to merge durations with equal signs.

      Parameters:
      timespan - other time span this duration will be merged with by adding the partial amounts
      Returns:
      new merged duration
      Throws:
      IllegalStateException - if the result gets mixed signs by adding the partial amounts
      IllegalArgumentException - if different units of same length exist
      ArithmeticException - in case of long overflow
      See Also:
      union(TimeSpan)
    • with

      public Duration<U> with(long amount, U unit)

      Gets a copy of this duration where the partial amount associated with given time unit is changed.

      Equivalent to plus(amount - getAmount(unit), unit).

      Parameters:
      amount - temporal amount to be set (maybe negative)
      unit - associated time unit
      Returns:
      new changed duration while this duration remains unaffected
      Throws:
      IllegalStateException - if the result gets mixed signs by setting the partial amounts
      IllegalArgumentException - if different units of same length exist
      ArithmeticException - in case of long overflow
      See Also:
      plus(long, U)
    • abs

      public Duration<U> abs()

      Gets the absolute always non-negative copy of this duration.

      Example:

        System.out.println(Duration.of(-5, MONTHS).abs());
        // output: P5M
       
      Returns:
      new positive duration if this duration is negative else this duration unchanged
      See Also:
      isNegative(), inverse()
    • inverse

      public Duration<U> inverse()

      Gets a copy of this duration with reversed sign.

      A double call of this method will yield an equal duration so following invariant holds:

        System.out.println(this.inverse().inverse().equals(this));
        // output: true
       

      For the special case of an empty duration, this method has no effect and just returns the same instance. The method is equivalent to the expression multipliedBy(-1).

      Example:

        System.out.println(Duration.of(-5, MONTHS).inverse());
        // output: P5M
       
      Specified by:
      inverse in class AbstractDuration<U extends IsoUnit>
      Returns:
      new negative duration if this duration is positive else a new positive duration with the same partial amounts and units
      See Also:
      isNegative(), multipliedBy(int)
    • multipliedBy

      public Duration<U> multipliedBy(int factor)

      Multiplies all partial amounts of this duration by given factor.

      Is the factor equal to 0 then the new duration is empty. If the factor 1 is specified then the method will just yield this instance unaffected. In the case of a negative factor the sign will also be inverted.

      Parameters:
      factor - multiplication factor
      Returns:
      new duration with all amounts multiplied while this duration remains unaffected
      Throws:
      ArithmeticException - in case of long overflow
    • union

      public List<Duration<U>> union(TimeSpan<? extends U> timespan)

      Creates a duration as union of this instance and given timespan where partial amounts of equal units will be summed up.

      The list result of this method can be used in time arithmetic as follows:

        Duration<CalendarUnit> dateDur =
            Duration.ofCalendarUnits(2, 7, 10);
        Duration<ClockUnit> timeDur =
            Duration.ofClockUnits(0, 30, 0);
        PlainTimestamp tsp = PlainTimestamp.of(2014, 1, 1, 0, 0);
      
        for (Duration<?> dur : Duration.ofZero().plus(dateDur).union(timeDur)) {
              tsp = tsp.plus(dur);
        }
      
        System.out.println(tsp); // 2016-08-11T00:30
       

      Note that this example will even work in case of mixed signs. No exception will be thrown. Instead this duration and the other one would just be added to the timestamp within a loop - step by step. In contrast to plus(TimeSpan), Time4J does not try to normalize the durations in order to produce a unique sign (on best effort base) in case of mixed signs.

      Parameters:
      timespan - other time span this duration is to be merged with
      Returns:
      unmodifiable list with one new merged duration or two unmerged durations in case of mixed signs
      Throws:
      IllegalArgumentException - if different units of same length exist
      ArithmeticException - in case of long overflow
      See Also:
      plus(TimeSpan)
    • compose

      public static Duration<IsoUnit> compose(Duration<CalendarUnit> calendarPeriod, Duration<ClockUnit> clockPeriod)

      Creates a composition of a calendar period and a clock period.

      Parameters:
      calendarPeriod - calendrical duration
      clockPeriod - duration with clock units
      Returns:
      composite duration
      Since:
      3.0
      See Also:
      toCalendarPeriod(), toClockPeriod()
    • toCalendarPeriod

      public Duration<CalendarUnit> toCalendarPeriod()

      Extracts a new duration with all contained calendar units only.

      The clock time part will be removed.

      Returns:
      new duration with calendar units only
      Since:
      3.0
      See Also:
      compose(Duration, Duration), toClockPeriod()
    • toClockPeriod

      public Duration<ClockUnit> toClockPeriod()

      Extracts a new duration with all contained clock units only.

      The calendrical part will be removed.

      Returns:
      new duration with clock units only
      Since:
      3.0
      See Also:
      compose(Duration, Duration), toCalendarPeriod(), toClockPeriodWithDaysAs24Hours()
    • toClockPeriodWithDaysAs24Hours

      public Duration<ClockUnit> toClockPeriodWithDaysAs24Hours()

      Extracts a new duration with all contained clock units only.

      The calendrical part will be removed with the exception of the days which will be converted into hours (on the base 1 day = 24 hours).

      Returns:
      new duration with clock units only
      Since:
      3.28/4.24
      See Also:
      compose(Duration, Duration), toCalendarPeriod()
    • toTemporalAmount

      public TemporalAmount toTemporalAmount()

      Converts this duration to a general temporal amount compatible with JSR-310-spec.

      The conversion is possible if and only if following units are part of this duration:

      • CalendarUnit.MILLENNIA
      • CalendarUnit.CENTURIES
      • CalendarUnit.DECADES
      • CalendarUnit.YEARS
      • CalendarUnit.QUARTERS
      • CalendarUnit.MONTHS
      • CalendarUnit.WEEKS
      • CalendarUnit.DAYS
      • ClockUnit.HOURS
      • ClockUnit.MINUTES
      • ClockUnit.SECONDS
      • ClockUnit.MILLIS
      • ClockUnit.MICROS
      • ClockUnit.NANOS
      • CalendarUnit.weekBasedYears()

      The resulting temporal amount is preferred to be applied on the local types of JSR-310 for the sake of conceptual clarity so the general mapping using this method looks like:

      • Duration<IsoUnit> can be applied on LocalDateTime
      • Duration<CalendarUnit> can be applied on LocalDate
      • Duration<ClockUnit> can be applied on LocalTime

      Other temporal types of JSR-310 might be supported, too (like YearMonth or ZonedDateTime). Note that using this method cannot be type-safe due to the design of JSR-310 (possibly throwing an exception at runtime) and includes some performance penalty because of the costs of conversion. Users should rather use Time4J-types for achieving best results.

      Returns:
      temporal amount applicable on JSR-310-types if they support all units of this duration
      Throws:
      UnsupportedOperationException - if this duration contains any unit not listed above
      Since:
      4.17
    • with

      public Duration<U> with(Normalizer<U> normalizer)

      Normalizes this duration by given normalizer.

      Parameters:
      normalizer - help object for normalizing this duration
      Returns:
      new normalized duration while this duration remains unaffected
      See Also:
      STD_PERIOD, STD_CALENDAR_PERIOD, STD_CLOCK_PERIOD, approximateHours(int), approximateMinutes(int), approximateSeconds(int), ClockUnit.only()
    • truncatedTo

      public Duration<U> truncatedTo(U unit)

      Sets all duration parts to zero whose unit has a smaller length than given unit.

      Parameters:
      unit - the minimum unit whose associated amount might still be non-zero
      Returns:
      truncated duration
      Since:
      5.2
    • approximateHours

      public static Normalizer<IsoUnit> approximateHours(int steps)

      Yields an approximate normalizer in steps of hours which finally uses years, months, days and rounded hours.

      The rounding algorithm consists of a combination of integer division and multiplication using the given step width. Example for suppressing hours (and all smaller units) by mean of an extra big step width of 24 hours (= 1 day):

        Duration<IsoUnit> dur =
            Duration.ofPositive().years(2).months(13).days(35)
                    .minutes(132).build()
                    .with(Duration.approximateHours(24));
        System.out.println(dur); // output: P3Y2M4D
       

      Another example for rounded hours using static imports:

        System.out.println(Duration.<IsoUnit>of(7, HOURS).with(approximateHours(3)));
        // output: PT6H
       
      Parameters:
      steps - rounding step width
      Returns:
      new normalizer for fuzzy and approximate durations
      Throws:
      IllegalArgumentException - if the argument is not positive
      Since:
      2.0
    • approximateMinutes

      public static Normalizer<IsoUnit> approximateMinutes(int steps)

      Yields an approximate normalizer in steps of minutes which finally uses years, months, days, hours and rounded minutes.

      Parameters:
      steps - rounding step width
      Returns:
      new normalizer for fuzzy and approximate durations
      Throws:
      IllegalArgumentException - if the argument is not positive
      Since:
      2.0
      See Also:
      approximateHours(int)
    • approximateSeconds

      public static Normalizer<IsoUnit> approximateSeconds(int steps)

      Yields an approximate normalizer in steps of seconds which finally uses years, months, days, hours, minutes and rounded seconds.

      Parameters:
      steps - rounding step width
      Returns:
      new normalizer for fuzzy and approximate durations
      Throws:
      IllegalArgumentException - if the argument is not positive
      Since:
      2.0
      See Also:
      approximateHours(int)
    • approximateMaxUnitOnly

      public static Normalizer<IsoUnit> approximateMaxUnitOnly()

      Creates a normalizer which yields an approximate duration based on the maximum relevant unit of the original duration (but not smaller than seconds).

      Example:

           assertThat(
                Duration.<IsoUnit>of(60 * 60 * 24 * 365, ClockUnit.SECONDS)
                    .with(Duration.approximateMaxUnitOnly()),
                is(Duration.of(1, YEARS)));
       

      Note: Due to the nature of this approximation-based normalization, exact results cannot be expected. Subsecond components are ignored.

      Returns:
      new normalizer for fuzzy and approximate durations of only one unit (either years, months, days, hours, minutes or seconds)
      Since:
      3.14/4.11
      See Also:
      approximateHours(int), approximateMinutes(int), approximateSeconds(int)
    • approximateMaxUnitOrWeeks

      public static Normalizer<IsoUnit> approximateMaxUnitOrWeeks()

      Like approximateMaxUnitOnly() but can create week-based durations if the count of days is bigger than 6.

      Returns:
      new normalizer for fuzzy and approximate durations of only one unit (either years, months, weeks/days, hours, minutes or seconds)
      Since:
      3.14/4.11
      See Also:
      approximateMaxUnitOnly()
    • summingUp

      public static <U extends IsoUnit> Collector<Duration<U>,​?,​Duration<U>> summingUp()

      Helps to sum up durations of a stream.

      Note: A normalization of the result is not yet done.

      Example for summing up a list of durations and final normalization:

           List<Duration<ClockUnit>> list = new ArrayList<>();
           list.add(Duration.of(11, ClockUnit.HOURS));
           list.add(Duration.ofClockUnits(4, 35, 121));
           list.add(Duration.of(10, ClockUnit.MINUTES));
      
           Duration<ClockUnit> expected = Duration.ofClockUnits(15, 47, 1);
      
           assertThat(
                list.stream().collect(Duration.summingUp()).with(Duration.STD_CLOCK_PERIOD),
                is(expected));
       
      Type Parameters:
      U - generic type of time units
      Returns:
      Collector for summing up durations in a stream
      Since:
      5.0
    • equals

      public boolean equals(Object obj)

      Based on all stored duration items and the sign.

      Overrides:
      equals in class Object
      Returns:
      true if obj is also a Duration, has the same units and amounts, the same sign and the same calendrical status else false
      See Also:
      getTotalLength(), isNegative()
    • hashCode

      public int hashCode()

      Computes the hash code.

      Overrides:
      hashCode in class Object
    • toString

      public String toString()

      Gets a canonical representation which optionally starts with a negative sign then continues with the letter "P", followed by a sequence of alphanumerical chars similar to the definition given in ISO-8601.

      Example: In ISO-8601 a duration of one month, three days and four hours is described as "P1M3DT4H". The special char "T" separates date and time part. Units are normally printed using their symbols, as second alternative using the output of their toString()-method within curly brackets.

      Is the duration negative then the representation will have a preceding minus sign as specified by XML-schema (for example "-P2D") while an empty duration will always have the format "PT0S" (second as universal unit). If the second part is also fractional then this method will use the comma as decimal separator char as recommended by ISO-8601.

      Note: The latter ISO-recommendation to use the comma as decimal separator char can be overriden by setting the system property "net.time4j.format.iso.decimal.dot" to "true" so that the english variation of a dot will be choosen instead.

      Overrides:
      toString in class AbstractDuration<U extends IsoUnit>
      Returns:
      String
      See Also:
      toStringISO(), toStringXML(), parsePeriod(String)
    • toStringISO

      public String toStringISO()

      Gets a canonical representation which starts with the letter "P", followed by a sequence of alphanumerical chars as defined in ISO-8601.

      A negative sign is not defined in ISO-8601 and will be rejected by this method with an exception. An empty duration will always have the format "PT0S" (second as universal unit). If the second part is also fractional then this method will use the comma as decimal separator char as recommended by ISO-8601.

      Note: The latter ISO-recommendation to use the comma as decimal separator char can be overriden by setting the system property "net.time4j.format.iso.decimal.dot" to "true" so that the english variation of a dot will be choosen instead. Furthermore, weeks are normalized to days if there are other calendrical units like years or months.

      Only units of types CalendarUnit or ClockUnit can be printed.

      Returns:
      String
      Throws:
      ChronoException - if this duration is negative or if any special units shall be output, but units of type CalendarUnit will be translated to iso-compatible units if necessary
      See Also:
      parsePeriod(String), IsoUnit.getSymbol()
    • toStringXML

      public String toStringXML()

      Gets a canonical representation conforming to XML-schema which optionally starts with a negative sign then continues with the letter "P", followed by a sequence of alphanumerical chars similar to the definition given in ISO-8601.

      Is the duration negative then the representation will have a preceding minus sign as specified by XML-schema (for example "-P2D") while an empty duration will always have the format "PT0S" (second as universal unit). If the second part is also fractional then this method will use the dot as decimal separator char (deviating specification in XML-schema). Weeks will always be normalized to days.

      Only units of types CalendarUnit or ClockUnit can be printed.

      Returns:
      String
      Throws:
      ChronoException - if any special units shall be output, but units of type CalendarUnit will be translated to xml-compatible units if necessary
      See Also:
      parsePeriod(String), IsoUnit.getSymbol()
    • parsePeriod

      public static Duration<IsoUnit> parsePeriod(String period) throws ParseException

      Parses a canonical representation to a duration.

      Canonical representations which start with the literal P are also called "period" in Time4J (P-string). This format is strongly recommended for storage in databases or XML. Syntax in a notation similar to regular expressions:

        sign := [-]?
        amount := [0-9]+
        fraction := [,\.]{amount}
        years-months-days := ({amount}Y)?({amount}M)?({amount}D)?
        weeks := ({amount}W)?
        date := {years-months-days} | {weeks}
        time := ({amount}H)?({amount}M)?({amount}{fraction}?S)?
        period := {sign}P{date}(T{time})? | PT{time}
       

      The units MILLENNIA, CENTURIES, DECADES and QUARTERS defined in CalendarUnit are supported but not special units like CalendarUnit.weekBasedYears().

      Furthermore there is the constraint that the symbols P and T must be followed by at least one duration item of amount and unit. All items with zero amount will be ignored however. The only item which is allowed to have a fractional part is SECONDS and can contain a comma as well as a dot as decimal separator. In ISO-8601 the comma is the preferred char, in XML-schema only the dot is allowed. If this parser is used in context of XML-schema (type xs:duration) it must be stated that week items are missing in contrast to ISO-8601. The method toStringXML() takes into account these characteristics of XML-schema (leaving aside the fact that XML-schema is potentially designed for unlimited big amounts but Time4J can define durations only in long range with nanosecond precision at best).

      Note: The alternative ISO-formats PYYYY-MM-DDThh:mm:ss and PYYYY-DDDThh:mm:ss and their basic variants are supported since version v2.0.

      Examples for supported formats:

        date := -P7Y4M3D (negative: 7 years, 4 months, 3 days)
        time := PT3H2M1,4S (positive: 3 hours, 2 minutes, 1400 milliseconds)
        date-time := P1Y1M5DT15H59M10.400S (dot as decimal separator)
        alternative := P0000-02-15T17:45
       
      Parameters:
      period - duration in canonical, ISO-8601-compatible or XML-schema-compatible format (P-string)
      Returns:
      parsed duration in all possible standard units of date and time
      Throws:
      ParseException - if parsing fails
      Since:
      1.2.1
      See Also:
      parseCalendarPeriod(String), parseClockPeriod(String), toString(), toStringISO(), toStringXML()
    • parseCalendarPeriod

      public static Duration<CalendarUnit> parseCalendarPeriod(String period) throws ParseException

      Parses a canonical representation with only date units to a calendrical duration.

      Parameters:
      period - duration in canonical, ISO-8601-compatible or XML-schema-compatible format (P-string)
      Returns:
      parsed calendrical duration
      Throws:
      ParseException - if parsing fails
      See Also:
      parsePeriod(String), parseClockPeriod(String)
    • parseClockPeriod

      public static Duration<ClockUnit> parseClockPeriod(String period) throws ParseException

      Parses a canonical representation with only wall time units to a time-only duration.

      Parameters:
      period - duration in canonical, ISO-8601-compatible or XML-schema-compatible format (P-string)
      Returns:
      parsed time-only duration
      Throws:
      ParseException - if parsing fails
      See Also:
      parsePeriod(String), parseCalendarPeriod(String)
    • parseWeekBasedPeriod

      public static Duration<IsoDateUnit> parseWeekBasedPeriod(String period) throws ParseException

      Parses a canonical representation with only week-based units (Y, W and D) to a calendrical duration where years are interpreted as week-based years with either 364 days (= 52 weeks) or 371 days (= 53 weeks).

      Parameters:
      period - duration in canonical or ISO-8601-compatible format (P-string)
      Returns:
      parsed calendrical duration
      Throws:
      ParseException - if parsing fails
      Since:
      3.21/4.17
      See Also:
      parsePeriod(String), CalendarUnit.weekBasedYears()
    • formatter

      public static Duration.Formatter<IsoUnit> formatter(String pattern)
      Parameters:
      pattern - format pattern
      Returns:
      new formatter instance
      Throws:
      IllegalArgumentException - in any case of pattern inconsistencies or failures
      Since:
      3.0
    • formatter

      public static <U extends IsoUnit> Duration.Formatter<U> formatter(Class<U> type, String pattern)
      Type Parameters:
      U - generic unit type
      Parameters:
      type - reified unit type
      pattern - format pattern
      Returns:
      new formatter instance
      Throws:
      IllegalArgumentException - in any case of pattern inconsistencies or failures
      Since:
      3.0