/*
* The MIT License (MIT)
*
* Copyright (c) 2015 Lachlan Dowding
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package permafrost.tundra.time;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.Calendar;
import java.util.Date;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.Duration;
/**
* A collection of convenience methods for working with durations.
*/
public final class DurationHelper {
public static final long MILLISECONDS_PER_SECOND = 1000;
public static final long MILLISECONDS_PER_MINUTE = 60 * MILLISECONDS_PER_SECOND;
public static final long MILLISECONDS_PER_HOUR = 60 * MILLISECONDS_PER_MINUTE;
public static final long MILLISECONDS_PER_DAY = 24 * MILLISECONDS_PER_HOUR;
public static final long MILLISECONDS_PER_WEEK = 7 * MILLISECONDS_PER_DAY;
private static final BigDecimal DECIMAL_ONE_THOUSAND = new BigDecimal(1000);
private static final BigInteger INTEGER_SEVEN = new BigInteger("7");
private static DatatypeFactory DATATYPE_FACTORY = null;
static {
try {
DATATYPE_FACTORY = DatatypeFactory.newInstance();
} catch (DatatypeConfigurationException ex) {
throw new RuntimeException(ex);
}
}
/**
* Disallow instantiation of this class.
*/
private DurationHelper() {}
/**
* Formats a duration string to the desired pattern.
*
* @param duration The duration string to be formatted.
* @param inPattern The pattern the duration string adheres to.
* @param outPattern The pattern the duration will be reformatted to.
* @return The duration string reformatted according to the outPattern.
*/
public static String format(String duration, String inPattern, String outPattern) {
return format(duration, inPattern, outPattern, null);
}
/**
* Formats a duration string to the desired pattern.
*
* @param duration The duration string to be formatted.
* @param inPattern The pattern the duration string adheres to.
* @param outPattern The pattern the duration will be reformatted to.
* @return The duration string reformatted according to the outPattern.
*/
public static String format(String duration, DurationPattern inPattern, DurationPattern outPattern) {
return format(duration, inPattern, outPattern, (Date)null);
}
/**
* Formats a duration in milliseconds to the desired pattern.
*
* @param milliseconds The duration to be formatted, specified as milliseconds.
* @param pattern The pattern the duration will be reformatted to.
* @return The duration reformatted according to the given pattern.
*/
public static String format(long milliseconds, DurationPattern pattern) {
return emit(parse(milliseconds), pattern);
}
/**
* Formats a duration in fractional seconds to the desired pattern.
*
* @param seconds The duration to be formatted, specified as fractional seconds.
* @param pattern The pattern the duration will be reformatted to.
* @return The duration reformatted according to the given pattern.
*/
public static String format(double seconds, DurationPattern pattern) {
return emit(parse(seconds), pattern);
}
/**
* Formats a duration in fractional seconds to the desired pattern.
*
* @param seconds The duration to be formatted, specified as fractional seconds.
* @param precision The number of decimal places to be respected in the given fraction.
* @param pattern The pattern the duration will be reformatted to.
* @return The duration reformatted according to the given pattern.
*/
public static String format(double seconds, int precision, DurationPattern pattern) {
return emit(parse(seconds, precision), pattern);
}
/**
* Formats a duration string to the desired pattern.
*
* @param duration The duration string to be formatted.
* @param inPattern The pattern the duration string adheres to.
* @param outPattern The pattern the duration will be reformatted to.
* @param datetime An XML datetime string used as a starting instant to resolve indeterminate values (such as the
* number of days in a month).
* @return The duration string reformatted according to the outPattern.
*/
public static String format(String duration, String inPattern, String outPattern, String datetime) {
return format(duration, inPattern, outPattern, datetime, null);
}
/**
* Formats a duration string to the desired pattern.
*
* @param duration The duration string to be formatted.
* @param inPattern The pattern the duration string adheres to.
* @param outPattern The pattern the duration will be reformatted to.
* @param datetime A datetime string used as a starting instant to resolve indeterminate values (such as the
* number of days in a month).
* @param datetimePattern The pattern the given datetime adheres to.
* @return The duration string reformatted according to the outPattern.
*/
public static String format(String duration, String inPattern, String outPattern, String datetime, String datetimePattern) {
return format(duration, DurationPattern.normalize(inPattern), DurationPattern.normalize(outPattern), datetime, datetimePattern);
}
/**
* Formats a duration string to the desired pattern.
*
* @param duration The duration string to be formatted.
* @param inPattern The pattern the duration string adheres to.
* @param outPattern The pattern the duration will be reformatted to.
* @param datetime A datetime string used as a starting instant to resolve indeterminate values (such as the
* number of days in a month).
* @param datetimePattern The pattern the given datetime adheres to.
* @return The duration string reformatted according to the outPattern.
*/
public static String format(String duration, DurationPattern inPattern, DurationPattern outPattern, String datetime, String datetimePattern) {
return format(duration, inPattern, outPattern, DateTimeHelper.parse(datetime, datetimePattern));
}
/**
* Formats a duration string to the desired pattern.
*
* @param duration The duration string to be formatted.
* @param inPattern The pattern the duration string adheres to.
* @param outPattern The pattern the duration will be reformatted to.
* @param instant A java.util.Calendar used as a starting instant to resolve indeterminate values (such as the
* number of days in a month).
* @return The duration string reformatted according to the outPattern.
*/
public static String format(String duration, DurationPattern inPattern, DurationPattern outPattern, Calendar instant) {
return format(duration, inPattern, outPattern, instant == null ? null : instant.getTime());
}
/**
* Formats a duration string to the desired pattern.
*
* @param duration The duration string to be formatted.
* @param inPattern The pattern the duration string adheres to.
* @param outPattern The pattern the duration will be reformatted to.
* @param instant A java.util.Date used as a starting instant to resolve indeterminate values (such as the number
* of days in a month).
* @return The duration string reformatted according to the outPattern.
*/
public static String format(String duration, DurationPattern inPattern, DurationPattern outPattern, Date instant) {
return emit(parse(duration, inPattern), outPattern, instant);
}
/**
* Formats a list of duration strings to the desired pattern.
*
* @param durations The duration strings to be formatted.
* @param inPattern The pattern the duration strings adhere to.
* @param outPattern The pattern the durations will be reformatted to.
* @return The duration strings reformatted according to the outPattern.
*/
public static String[] format(String[] durations, String inPattern, String outPattern) {
return format(durations, inPattern, outPattern, null);
}
/**
* Formats a list of duration strings to the desired pattern.
*
* @param durations The duration strings to be formatted.
* @param inPattern The pattern the duration strings adhere to.
* @param outPattern The pattern the durations will be reformatted to.
* @param datetime An XML datetime string used as a starting instant to resolve indeterminate values (such as the
* number of days in a month).
* @return The duration strings reformatted according to the outPattern.
*/
public static String[] format(String[] durations, String inPattern, String outPattern, String datetime) {
return format(durations, inPattern, outPattern, datetime, null);
}
/**
* Formats a list of duration strings to the desired pattern.
*
* @param durations The duration strings to be formatted.
* @param inPattern The pattern the duration strings adhere to.
* @param outPattern The pattern the durations will be reformatted to.
* @param datetime A datetime string used as a starting instant to resolve indeterminate values (such as the
* number of days in a month).
* @param datetimePattern The pattern the given datetime adheres to.
* @return The duration strings reformatted according to the outPattern.
*/
public static String[] format(String[] durations, String inPattern, String outPattern, String datetime, String datetimePattern) {
return format(durations, DurationPattern.normalize(inPattern), DurationPattern.normalize(outPattern), datetime, datetimePattern);
}
/**
* Formats a list of duration strings to the desired pattern.
*
* @param durations The duration strings to be formatted.
* @param inPattern The pattern the duration strings adhere to.
* @param outPattern The pattern the durations will be reformatted to.
* @return The duration strings reformatted according to the outPattern.
*/
public static String[] format(String[] durations, DurationPattern inPattern, DurationPattern outPattern) {
return format(durations, inPattern, outPattern, (Date)null);
}
/**
* Formats a list of duration strings to the desired pattern.
*
* @param durations The duration strings to be formatted.
* @param inPattern The pattern the duration strings adhere to.
* @param outPattern The pattern the durations will be reformatted to.
* @param datetime A datetime string used as a starting instant to resolve indeterminate values (such as the
* number of days in a month).
* @param datetimePattern The pattern the given datetime adheres to.
* @return The duration strings reformatted according to the outPattern.
*/
public static String[] format(String[] durations, DurationPattern inPattern, DurationPattern outPattern, String datetime, String datetimePattern) {
return format(durations, inPattern, outPattern, DateTimeHelper.parse(datetime, datetimePattern));
}
/**
* Formats a list of duration strings to the desired pattern.
*
* @param durations The duration strings to be formatted.
* @param inPattern The pattern the duration strings adhere to.
* @param outPattern The pattern the durations will be reformatted to.
* @param instant A java.util.Calendar used as a starting instant to resolve indeterminate values (such as the
* number of days in a month).
* @return The duration strings reformatted according to the outPattern.
*/
public static String[] format(String[] durations, DurationPattern inPattern, DurationPattern outPattern, Calendar instant) {
return format(durations, inPattern, outPattern, instant == null ? null : instant.getTime());
}
/**
* Formats a list of duration strings to the desired pattern.
*
* @param durations The duration strings to be formatted.
* @param inPattern The pattern the duration strings adhere to.
* @param outPattern The pattern the durations will be reformatted to.
* @param instant A java.util.Date used as a starting instant to resolve indeterminate values (such as the number
* of days in a month).
* @return The duration strings reformatted according to the outPattern.
*/
public static String[] format(String[] durations, DurationPattern inPattern, DurationPattern outPattern, Date instant) {
return emit(parse(durations, inPattern), outPattern, instant);
}
/**
* Returns a new Duration given a duration in milliseconds.
*
* @param milliseconds The duration in milliseconds.
* @return A Duration object representing the duration in milliseconds.
*/
public static Duration parse(long milliseconds) {
return DATATYPE_FACTORY.newDuration(milliseconds);
}
/**
* Returns a new Duration given a duration in fractional seconds.
*
* @param seconds The duration in fractional seconds.
* @return A Duration object representing the duration in fractional seconds.
*/
public static Duration parse(double seconds) {
return DATATYPE_FACTORY.newDuration(seconds >= 0.0, null, null, null, null, null, new BigDecimal(seconds).abs());
}
/**
* Returns a new Duration given a duration in fractional seconds.
*
* @param seconds The duration in fractional seconds.
* @param precision The number of decimal places to respect int the given fraction.
* @return A Duration object representing the duration in fractional seconds.
*/
public static Duration parse(double seconds, int precision) {
return DATATYPE_FACTORY.newDuration(seconds >= 0.0, null, null, null, null, null, (new BigDecimal(seconds)).abs().setScale(precision, RoundingMode.HALF_UP));
}
/**
* Parses the given duration string to a Duration object.
*
* @param input The duration string to be parsed.
* @return A Duration object which represents the given duration string.
*/
public static Duration parse(String input) {
return parse(input, (DurationPattern)null);
}
/**
* Parses the given duration string to a Duration object.
*
* @param input The duration string to be parsed.
* @param pattern The pattern the duration string adheres to.
* @return A Duration object which represents the given duration string.
*/
public static Duration parse(String input, String pattern) {
return parse(input, DurationPattern.normalize(pattern));
}
/**
* Parses the given duration string to a Duration object.
*
* @param input The duration string to be parsed.
* @param pattern The pattern the duration string adheres to.
* @return A Duration object which represents the given duration string.
*/
public static Duration parse(String input, DurationPattern pattern) {
if (input == null) return null;
pattern = DurationPattern.normalize(pattern);
Duration output = null;
try {
if (pattern == DurationPattern.XML) {
output = DATATYPE_FACTORY.newDuration(input);
} else {
BigDecimal decimalValue = new BigDecimal(input);
BigInteger integerValue = decimalValue.toBigInteger();
switch (pattern) {
case MILLISECONDS:
// convert milliseconds to fractional seconds
decimalValue = decimalValue.divide(DECIMAL_ONE_THOUSAND);
output = DATATYPE_FACTORY.newDuration(decimalValue.compareTo(BigDecimal.ZERO) >= 0, null, null, null, null, null, decimalValue.abs());
break;
case SECONDS:
output = DATATYPE_FACTORY.newDuration(decimalValue.compareTo(BigDecimal.ZERO) >= 0, null, null, null, null, null, decimalValue.abs());
break;
case MINUTES:
output = DATATYPE_FACTORY.newDuration(integerValue.compareTo(BigInteger.ZERO) >= 0, null, null, null, null, integerValue.abs(), null);
break;
case HOURS:
output = DATATYPE_FACTORY.newDuration(integerValue.compareTo(BigInteger.ZERO) >= 0, null, null, null, integerValue.abs(), null, null);
break;
case DAYS:
output = DATATYPE_FACTORY.newDuration(integerValue.compareTo(BigInteger.ZERO) >= 0, null, null, integerValue.abs(), null, null, null);
break;
case WEEKS:
// convert weeks to days by multiplying by 7
integerValue = integerValue.multiply(INTEGER_SEVEN);
output = DATATYPE_FACTORY.newDuration(integerValue.compareTo(BigInteger.ZERO) >= 0, null, null, integerValue.abs(), null, null, null);
break;
case MONTHS:
output = DATATYPE_FACTORY.newDuration(integerValue.compareTo(BigInteger.ZERO) >= 0, null, integerValue.abs(), null, null, null, null);
break;
case YEARS:
output = DATATYPE_FACTORY.newDuration(integerValue.compareTo(BigInteger.ZERO) >= 0, integerValue.abs(), null, null, null, null, null);
break;
default:
throw new IllegalArgumentException("Unsupported duration pattern: " + pattern);
}
}
} catch (IllegalArgumentException ex) {
throw new IllegalArgumentException("Unparseable duration: '" + input + "' does not conform to pattern '" + pattern.toString() + "'", ex);
}
return output;
}
/**
* Parses the given duration strings to Duration objects.
*
* @param input The list of duration strings to be parsed.
* @return A list of Duration objects which represents the given duration strings.
*/
public static Duration[] parse(String[] input) {
return parse(input, (DurationPattern)null);
}
/**
* Parses the given duration strings to Duration objects.
*
* @param input The list of duration strings to be parsed.
* @param pattern The pattern the duration strings adhere to.
* @return A list of Duration objects which represents the given duration strings.
*/
public static Duration[] parse(String[] input, String pattern) {
return parse(input, DurationPattern.normalize(pattern));
}
/**
* Parses the given duration strings to Duration objects.
*
* @param input The list of duration strings to be parsed.
* @param pattern The pattern the duration strings adhere to.
* @return A list of Duration objects which represents the given duration strings.
*/
public static Duration[] parse(String[] input, DurationPattern pattern) {
if (input == null) return null;
pattern = DurationPattern.normalize(pattern);
Duration[] output = new Duration[input.length];
for (int i = 0; i < input.length; i++) {
output[i] = parse(input[i], pattern);
}
return output;
}
/**
* Returns the given duration as an XML duration string.
*
* @param input The duration to be serialized.
* @return An XML duration string representing the given duration.
*/
public static String emit(Duration input) {
return emit(input, (DurationPattern)null);
}
/**
* Returns the given duration as a duration string formatted to the desired pattern.
*
* @param input The duration to be serialized.
* @param pattern The pattern to use to format the duration string.
* @return A duration string formatted according to the pattern representing the given duration.
*/
public static String emit(Duration input, String pattern) {
return emit(input, pattern, null);
}
/**
* Returns the given duration as a duration string formatted to the desired pattern.
*
* @param input The duration to be serialized.
* @param pattern The pattern to use to format the duration string.
* @return A duration string formatted according to the pattern representing the given duration.
*/
public static String emit(Duration input, DurationPattern pattern) {
return emit(input, pattern, (Date)null);
}
/**
* Returns the given duration as a duration string formatted to the desired pattern.
*
* @param input The duration to be serialized.
* @param pattern The pattern to use to format the duration string.
* @param datetime A datetime string used as a starting instant to resolve indeterminate values (such as the number
* of days in a month).
* @return A duration string formatted according to the pattern representing the given duration.
*/
public static String emit(Duration input, String pattern, String datetime) {
return emit(input, pattern, datetime, null);
}
/**
* Returns the given duration as a duration string formatted to the desired pattern.
*
* @param input The duration to be serialized.
* @param pattern The pattern to use to format the duration string.
* @param datetime A datetime string used as a starting instant to resolve indeterminate values (such as the
* number of days in a month).
* @param datetimePattern The pattern the given datetime adheres to.
* @return A duration string formatted according to the pattern representing the given duration.
*/
public static String emit(Duration input, String pattern, String datetime, String datetimePattern) {
return emit(input, DurationPattern.normalize(pattern), datetime, datetimePattern);
}
/**
* Returns the given duration as a duration string formatted to the desired pattern.
*
* @param input The duration to be serialized.
* @param pattern The pattern to use to format the duration string.
* @param datetime A datetime string used as a starting instant to resolve indeterminate values (such as the
* number of days in a month).
* @param datetimePattern The pattern the given datetime adheres to.
* @return A duration string formatted according to the pattern representing the given duration.
*/
public static String emit(Duration input, DurationPattern pattern, String datetime, String datetimePattern) {
return emit(input, pattern, DateTimeHelper.parse(datetime, datetimePattern));
}
/**
* Returns the given duration as a duration string formatted to the desired pattern.
*
* @param input The duration to be serialized.
* @param pattern The pattern to use to format the duration string.
* @param instant A java.util.Calendar used as a starting instant to resolve indeterminate values (such as the
* number of days in a month).
* @return A duration string formatted according to the pattern representing the given duration.
*/
public static String emit(Duration input, DurationPattern pattern, Calendar instant) {
return emit(input, pattern, instant == null ? null : instant.getTime());
}
/**
* Returns the given duration as a duration string formatted to the desired pattern.
*
* @param input The duration to be serialized.
* @param pattern The pattern to use to format the duration string.
* @param instant A java.util.Date used as a starting instant to resolve indeterminate values (such as the number of
* days in a month).
* @return A duration string formatted according to the pattern representing the given duration.
*/
public static String emit(Duration input, DurationPattern pattern, Date instant) {
if (input == null) return null;
if (instant == null) instant = new Date();
pattern = DurationPattern.normalize(pattern);
String output = null;
switch (pattern) {
case MILLISECONDS:
output = "" + input.getTimeInMillis(instant);
break;
case SECONDS:
output = "" + (input.getTimeInMillis(instant) / MILLISECONDS_PER_SECOND);
break;
case MINUTES:
output = "" + (input.getTimeInMillis(instant) / MILLISECONDS_PER_MINUTE);
break;
case HOURS:
output = "" + (input.getTimeInMillis(instant) / MILLISECONDS_PER_HOUR);
break;
case DAYS:
output = "" + (input.getTimeInMillis(instant) / MILLISECONDS_PER_DAY);
break;
case WEEKS:
output = "" + (input.getTimeInMillis(instant) / MILLISECONDS_PER_WEEK);
break;
case XML:
output = input.toString();
break;
default:
throw new IllegalArgumentException("Unsupported duration pattern: " + pattern);
}
return output;
}
/**
* Returns the given durations as XML duration strings.
*
* @param input The list of durations to be serialized.
* @return XML duration strings representing the given durations.
*/
public static String[] emit(Duration[] input) {
return emit(input, (String)null);
}
/**
* Returns the given durations as duration strings formatted to the desired pattern.
*
* @param input The list of durations to be serialized.
* @param pattern The pattern to use to format the duration strings.
* @return The duration strings formatted according to the pattern representing the given durations.
*/
public static String[] emit(Duration[] input, String pattern) {
return emit(input, pattern, null);
}
/**
* Returns the given durations as duration strings formatted to the desired pattern.
*
* @param input The list of durations to be serialized.
* @param pattern The pattern to use to format the duration strings.
* @return The duration strings formatted according to the pattern representing the given durations.
*/
public static String[] emit(Duration[] input, DurationPattern pattern) {
return emit(input, pattern, (Date)null);
}
/**
* Returns the given durations as duration strings formatted to the desired pattern.
*
* @param input The list of durations to be serialized.
* @param pattern The pattern to use to format the duration strings.
* @param datetime A datetime string used as a starting instant to resolve indeterminate values (such as the number
* of days in a month).
* @return The duration strings formatted according to the pattern representing the given duration.
*/
public static String[] emit(Duration[] input, String pattern, String datetime) {
return emit(input, pattern, datetime, null);
}
/**
* Returns the given durations as duration strings formatted to the desired pattern.
*
* @param input The list of durations to be serialized.
* @param pattern The pattern to use to format the duration strings.
* @param datetime A datetime string used as a starting instant to resolve indeterminate values (such as the
* number of days in a month).
* @param datetimePattern The pattern the given datetime adheres to.
* @return The duration strings formatted according to the pattern representing the given durations.
*/
public static String[] emit(Duration[] input, String pattern, String datetime, String datetimePattern) {
return emit(input, DurationPattern.normalize(pattern), datetime, datetimePattern);
}
/**
* Returns the given durations as duration strings formatted to the desired pattern.
*
* @param input The list of durations to be serialized.
* @param pattern The pattern to use to format the duration strings.
* @param datetime A datetime string used as a starting instant to resolve indeterminate values (such as the
* number of days in a month).
* @param datetimePattern The pattern the given datetime adheres to.
* @return The duration strings formatted according to the pattern representing the given durations.
*/
public static String[] emit(Duration[] input, DurationPattern pattern, String datetime, String datetimePattern) {
return emit(input, pattern, DateTimeHelper.parse(datetime, datetimePattern));
}
/**
* Returns the given durations as duration strings formatted to the desired pattern.
*
* @param input The list of durations to be serialized.
* @param pattern The pattern to use to format the duration strings.
* @param instant A java.util.Calendar used as a starting instant to resolve indeterminate values (such as the
* number of days in a month).
* @return The duration strings formatted according to the pattern representing the given durations.
*/
public static String[] emit(Duration input[], DurationPattern pattern, Calendar instant) {
return emit(input, pattern, instant == null ? null : instant.getTime());
}
/**
* Returns the given durations as duration strings formatted to the desired pattern.
*
* @param input The list of durations to be serialized.
* @param pattern The pattern to use to format the duration strings.
* @param instant A java.util.Date used as a starting instant to resolve indeterminate values (such as the number of
* days in a month).
* @return The duration strings formatted according to the pattern representing the given durations.
*/
public static String[] emit(Duration[] input, DurationPattern pattern, Date instant) {
if (input == null) return null;
if (instant == null) instant = new Date();
pattern = DurationPattern.normalize(pattern);
String[] output = new String[input.length];
for (int i = 0; i < input.length; i++) {
output[i] = emit(input[i], pattern, instant);
}
return output;
}
/**
* Adds the given list of durations together, returning the result.
*
* @param durations The list of durations to be added.
* @return The result of all the given durations added together.
*/
public static Duration add(Duration... durations) {
Duration result = DATATYPE_FACTORY.newDuration(0);
if (durations != null) {
for (int i = 0; i < durations.length; i++) {
if (durations[i] != null) {
result = result.add(durations[i]);
}
}
}
return result;
}
/**
* Subtracts the tail of the given list of durations from the head of the list, returning the result.
*
* @param durations The list of durations whose tail is to be subtracted from the head.
* @return The result of subtracting the tail of the list of durations from the head of the list.
*/
public static Duration subtract(Duration... durations) {
Duration result = DATATYPE_FACTORY.newDuration(0);
boolean first = true;
if (durations != null && durations.length > 0) {
for (int i = 0; i < durations.length; i++) {
if (durations[i] != null) {
if (first) {
result = durations[i]; // initialize result to first duration
first = false;
} else {
result = result.subtract(durations[i]);
}
}
}
}
return result;
}
/**
* Compares two durations, returning whether the first is less than, greater than, equal to, or cannot be compared
* (indeterminate) to the second duration.
*
* @param x The first duration to be compared.
* @param y The second duration to be compared.
* @return javax.xml.datatype.DatatypeConstants.LESSER if less than, javax.xml.datatype.DatatypeConstants.EQUAL if
* equal, javax.xml.datatype.DatatypeConstants.GREATER if greater than, javax.xml.datatype.DatatypeConstants.INDETERMINATE
* if durations cannot be compared.
*/
public static int compare(Duration x, Duration y) {
if (x == null && y == null) return DatatypeConstants.EQUAL;
if (x == null || y == null) return DatatypeConstants.INDETERMINATE;
return x.compare(y);
}
/**
* Negates the given duration.
*
* @param input The duration to be negated.
* @return The negated duration.
*/
public static Duration negate(Duration input) {
if (input == null) return null;
return input.negate();
}
/**
* Returns the given duration multiplied by the given factor.
*
* @param input The duration to be multiplied.
* @param factor The factor to multiply the duration by.
* @return The duration multiplied by the factor.
*/
public static Duration multiply(Duration input, BigDecimal factor) {
return multiply(input, factor, null, null);
}
/**
* Returns the given duration multiplied by the given factor.
*
* @param input The duration to be multiplied.
* @param factor The factor to multiply the duration by.
* @param datetime A datetime string used as a starting instant to resolve indeterminate values (such as the number
* of days in a month).
* @return The duration multiplied by the factor.
*/
public static Duration multiply(Duration input, BigDecimal factor, String datetime) {
return multiply(input, factor, datetime, null);
}
/**
* Returns the given duration multiplied by the given factor.
*
* @param input The duration to be multiplied.
* @param factor The factor to multiply the duration by.
* @param datetime A datetime string used as a starting instant to resolve indeterminate values (such as the
* number of days in a month).
* @param datetimePattern The pattern the given datetime adheres to.
* @return The duration multiplied by the factor.
*/
public static Duration multiply(Duration input, BigDecimal factor, String datetime, String datetimePattern) {
return multiply(input, factor, DateTimeHelper.parse(datetime, datetimePattern));
}
/**
* Returns the given duration multiplied by the given factor.
*
* @param input The duration to be multiplied.
* @param factor The factor to multiply the duration by.
* @param instant A java.util.Date used as a starting instant to resolve indeterminate values (such as the number of
* days in a month).
* @return The duration multiplied by the factor.
*/
public static Duration multiply(Duration input, BigDecimal factor, Date instant) {
return multiply(input, factor, DateTimeHelper.toCalendar(instant));
}
/**
* Returns the given duration multiplied by the given factor.
*
* @param input The duration to be multiplied.
* @param factor The factor to multiply the duration by.
* @param instant A java.util.Calendar used as a starting instant to resolve indeterminate values (such as the
* number of days in a month).
* @return The duration multiplied by the factor.
*/
public static Duration multiply(Duration input, BigDecimal factor, Calendar instant) {
if (input == null || factor == null) return input;
if (instant == null) instant = Calendar.getInstance();
return input.normalizeWith(instant).multiply(factor);
}
/**
* Normalizes the given object to a Duration object.
*
* @param input The object to be normalized.
* @param pattern The pattern the object adhere to, if it is a string.
* @return A Duration object which represents the given object.
*/
public static Duration normalize(Object input, String pattern) {
return normalize(input, DurationPattern.normalize(pattern));
}
/**
* Normalizes the given object to a Duration object.
*
* @param input The object to be normalized.
* @param pattern The pattern the object adhere to, if it is a string.
* @return A Duration object which represents the given object.
*/
public static Duration normalize(Object input, DurationPattern pattern) {
if (input == null) return null;
Duration output = null;
if (input instanceof String) {
output = parse((String)input, pattern);
} else if (input instanceof Number) {
output = parse(((Number)input).longValue());
} else if (input instanceof Duration) {
output = (Duration)input;
}
return output;
}
/**
* Normalizes the given objects to Duration objects.
*
* @param input The list of objects to be normalized.
* @param pattern The pattern the objects adhere to, if they are strings.
* @return A list of Duration objects which represents the given objects.
*/
public static Duration[] normalize(Object[] input, String pattern) {
return normalize(input, DurationPattern.normalize(pattern));
}
/**
* Normalizes the given objects to Duration objects.
*
* @param input The list of objects to be normalized.
* @param pattern The pattern the objects adhere to, if they are strings.
* @return A list of Duration objects which represents the given objects.
*/
public static Duration[] normalize(Object[] input, DurationPattern pattern) {
if (input == null) return null;
Duration[] output = new Duration[input.length];
for (int i = 0; i < input.length; i++) {
output[i] = normalize(input[i], pattern);
}
return output;
}
}