package marubinotto.util.time; import java.io.Serializable; import java.util.Arrays; import java.util.Collections; import marubinotto.util.Assert; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; /** * The period of time during which something continues. * * The class is named Duration, rather than Time, to make explicit the * distinction between a moment in time (as represented by the Date class in * Java) and an elapsed time, which this class represents. */ public class Duration implements Serializable, Comparable<Duration> { private long interval = 0; public Duration() { } public Duration(long milliseconds) { setMilliseconds(milliseconds); } protected void setMilliseconds(long milliseconds) { Assert.require(milliseconds >= 0, "milliseconds >= 0"); this.interval = milliseconds; } public static Duration parseSecond(String seconds) { double milliseconds = Double.parseDouble(seconds) * 1000; return new Duration((long) milliseconds); } public long getTime() { return this.interval; } public double getTime(Unit unit) { return this.interval / unit.getValue(); } public String[] decompose(Unit[] units) { Arrays.sort(units, Collections.reverseOrder()); long interval = this.interval; String[] components = new String[units.length]; for (int i = 0; i < units.length; i++) { int component = (int) (interval / units[i].getValue()); interval = interval % units[i].getValue(); components[i] = String.valueOf(component); if (i > 0) { int digit = units[i - 1].calculateDigit(units[i]); components[i] = StringUtils.leftPad(components[i], digit, '0'); } } return components; } public String getAsDefaultFormat() { String[] components = decompose(new Unit[]{Unit.HOUR, Unit.MINUTE, Unit.SECOND, Unit.MILLISECOND}); return components[0] + ":" + components[1] + ":" + components[2] + "." + components[3]; } public String getAsSecondFormat() { String[] components = decompose(new Unit[]{Unit.SECOND, Unit.MILLISECOND}); return components[0] + "." + components[1]; } public int compareTo(Duration another) { long anotherVal = another.interval; return (this.interval < anotherVal ? -1 : (this.interval == anotherVal ? 0 : 1)); } public String toString() { return getAsDefaultFormat(); } // Nested classes public static class Unit implements Comparable<Unit> { public static final Unit MILLISECOND = new Unit(1, "millisecond"); public static final Unit SECOND = new Unit(MILLISECOND.getValue() * 1000, "second"); public static final Unit MINUTE = new Unit(SECOND.getValue() * 60, "minute"); public static final Unit HOUR = new Unit(MINUTE.getValue() * 60, "hour"); public static final Unit DAY = new Unit(HOUR.getValue() * 24, "day"); public static final Unit WEEK = new Unit(DAY.getValue() * 7, "week"); public static final Unit MONTH = new Unit(DAY.getValue() * 30, "month"); public static final Unit YEAR = new Unit(DAY.getValue() * 365, "year"); private long value; private String name; public Unit(long value, String name) { this.value = value; this.name = name; } public long getValue() { return this.value; } public String getName() { return this.name; } public int calculateDigit(Unit lowerUnit) { Validate.isTrue(lowerUnit.getValue() < getValue(), "lowerUnit.getValue() < getValue()"); int times = (int) (getValue() / lowerUnit.getValue()); return String.valueOf(times - 1).length(); } public int compareTo(Unit another) { long anotherVal = another.value; return (this.value < anotherVal ? -1 : (this.value == anotherVal ? 0 : 1)); } } }