package org.sonar.api.utils;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+
import java.io.Serializable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public static final String HOUR = "h";
public static final String MINUTE = "min";
- private static final short HOURS_IN_ONE_DAY = 24;
private static final short MINUTES_IN_ONE_HOUR = 60;
private final long durationInMinutes;
- private int days;
- private int hours;
- private int minutes;
-
private Duration(long durationInMinutes) {
this.durationInMinutes = durationInMinutes;
- this.days = ((Double) ((double) durationInMinutes / HOURS_IN_ONE_DAY / MINUTES_IN_ONE_HOUR)).intValue();
- Long currentDurationInMinutes = durationInMinutes - (days * HOURS_IN_ONE_DAY * MINUTES_IN_ONE_HOUR);
- this.hours = ((Double) (currentDurationInMinutes.doubleValue() / MINUTES_IN_ONE_HOUR)).intValue();
- currentDurationInMinutes = currentDurationInMinutes - (hours * MINUTES_IN_ONE_HOUR);
- this.minutes = currentDurationInMinutes.intValue();
- }
-
- private Duration(int days, int hours, int minutes) {
- this(calculateDurationInMinutes(days, hours, minutes, HOURS_IN_ONE_DAY));
- }
-
- public static Duration ofDays(int days) {
- return new Duration(days, 0, 0);
}
- public static Duration ofHours(int hours) {
- return new Duration(0, hours, 0);
- }
-
- public static Duration ofMinutes(int minutes) {
- return new Duration(0, 0, minutes);
+ private Duration(int days, int hours, int minutes, int hoursInDay) {
+ this(((long) days * hoursInDay * MINUTES_IN_ONE_HOUR) + (hours * MINUTES_IN_ONE_HOUR) + minutes);
}
public static Duration create(long durationInMinutes) {
return new Duration(durationInMinutes);
}
- public static Duration decode(String text) {
- return new Duration(extractValue(text, DAY), extractValue(text, HOUR), extractValue(text, MINUTE));
+ public static Duration decode(String text, int hoursInDay) {
+ return new Duration(extractValue(text, DAY), extractValue(text, HOUR), extractValue(text, MINUTE), hoursInDay);
}
private static int extractValue(String text, String unit) {
}
return 0;
} catch (NumberFormatException e) {
- throw new IllegalArgumentException(String.format("'%s' is invalid, it should use the following sample format : 2d 10h 15min", text), e);
+ throw new IllegalArgumentException(String.format("Duration '%s' is invalid, it should use the following sample format : 2d 10h 15min", text), e);
}
}
- public String encode() {
- return toString();
- }
-
- public int days() {
- return days;
- }
-
- public int hours() {
- return hours;
- }
+ public String encode(int hoursInDay) {
+ int days = ((Double) ((double) durationInMinutes / hoursInDay / MINUTES_IN_ONE_HOUR)).intValue();
+ Long remainingDuration = durationInMinutes - (days * hoursInDay * MINUTES_IN_ONE_HOUR);
+ int hours = ((Double) (remainingDuration.doubleValue() / MINUTES_IN_ONE_HOUR)).intValue();
+ remainingDuration = remainingDuration - (hours * MINUTES_IN_ONE_HOUR);
+ int minutes = remainingDuration.intValue();
- public int minutes() {
- return minutes;
+ StringBuilder stringBuilder = new StringBuilder();
+ if (days > 0) {
+ stringBuilder.append(days);
+ stringBuilder.append(DAY);
+ }
+ if (hours > 0) {
+ stringBuilder.append(hours);
+ stringBuilder.append(HOUR);
+ }
+ if (minutes > 0) {
+ stringBuilder.append(minutes);
+ stringBuilder.append(MINUTE);
+ }
+ return stringBuilder.toString();
}
public long toMinutes() {
return durationInMinutes;
}
- public long toMinutes(int hoursInDay) {
- return calculateDurationInMinutes(days, hours, minutes, hoursInDay);
- }
-
- private static long calculateDurationInMinutes(int days, int hours, int minutes, int hoursInDay){
- return ((long) days * hoursInDay * MINUTES_IN_ONE_HOUR) + (hours * MINUTES_IN_ONE_HOUR) + minutes;
+ public boolean isGreaterThan(Duration other){
+ return toMinutes() > other.toMinutes();
}
@Override
@Override
public String toString() {
- StringBuilder stringBuilder = new StringBuilder();
- if (days > 0) {
- stringBuilder.append(days);
- stringBuilder.append(DAY);
- }
- if (hours > 0) {
- stringBuilder.append(hours);
- stringBuilder.append(HOUR);
- }
- if (minutes > 0) {
- stringBuilder.append(minutes);
- stringBuilder.append(MINUTE);
- }
- return stringBuilder.toString();
+ return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
}
public class DurationTest {
+ static final int HOURS_IN_DAY = 8;
+
static final Long ONE_MINUTE = 1L;
static final Long ONE_HOUR_IN_MINUTES = ONE_MINUTE * 60;
- static final Long ONE_DAY_IN_MINUTES = ONE_HOUR_IN_MINUTES * 24;
-
- @Test
- public void of_days() throws Exception {
- Duration duration = Duration.ofDays(1);
- assertThat(duration.days()).isEqualTo(1);
- assertThat(duration.hours()).isEqualTo(0);
- assertThat(duration.minutes()).isEqualTo(0);
- assertThat(duration.toMinutes()).isEqualTo(ONE_DAY_IN_MINUTES);
- }
-
- @Test
- public void of_hours() throws Exception {
- Duration duration = Duration.ofHours(1);
- assertThat(duration.days()).isEqualTo(0);
- assertThat(duration.hours()).isEqualTo(1);
- assertThat(duration.minutes()).isEqualTo(0);
- assertThat(duration.toMinutes()).isEqualTo(ONE_HOUR_IN_MINUTES);
-
- duration = Duration.ofHours(25);
- assertThat(duration.days()).isEqualTo(1);
- assertThat(duration.hours()).isEqualTo(1);
- assertThat(duration.minutes()).isEqualTo(0);
- assertThat(duration.toMinutes()).isEqualTo(ONE_DAY_IN_MINUTES + ONE_HOUR_IN_MINUTES);
- }
-
- @Test
- public void of_minutes() throws Exception {
- Duration duration = Duration.ofMinutes(1);
- assertThat(duration.days()).isEqualTo(0);
- assertThat(duration.hours()).isEqualTo(0);
- assertThat(duration.minutes()).isEqualTo(1);
- assertThat(duration.toMinutes()).isEqualTo(ONE_MINUTE);
-
- duration = Duration.ofMinutes(61);
- assertThat(duration.days()).isEqualTo(0);
- assertThat(duration.hours()).isEqualTo(1);
- assertThat(duration.minutes()).isEqualTo(1);
- assertThat(duration.toMinutes()).isEqualTo(ONE_HOUR_IN_MINUTES + ONE_MINUTE);
- }
+ static final Long ONE_DAY_IN_MINUTES = ONE_HOUR_IN_MINUTES * HOURS_IN_DAY;
@Test
public void create_from_duration_in_minutes() throws Exception {
Duration duration = Duration.create(ONE_DAY_IN_MINUTES + ONE_HOUR_IN_MINUTES + ONE_MINUTE);
- assertThat(duration.days()).isEqualTo(1);
- assertThat(duration.hours()).isEqualTo(1);
- assertThat(duration.minutes()).isEqualTo(1);
assertThat(duration.toMinutes()).isEqualTo(ONE_DAY_IN_MINUTES + ONE_HOUR_IN_MINUTES + ONE_MINUTE);
}
@Test
public void encode() throws Exception {
- assertThat(Duration.create(2 * ONE_DAY_IN_MINUTES + 5 * ONE_HOUR_IN_MINUTES + 46 * ONE_MINUTE).encode()).isEqualTo("2d5h46min");
- assertThat(Duration.create(ONE_DAY_IN_MINUTES).encode()).isEqualTo("1d");
- assertThat(Duration.create(ONE_HOUR_IN_MINUTES).encode()).isEqualTo("1h");
- assertThat(Duration.create(ONE_MINUTE).encode()).isEqualTo("1min");
+ assertThat(Duration.create(2 * ONE_DAY_IN_MINUTES + 5 * ONE_HOUR_IN_MINUTES + 46 * ONE_MINUTE).encode(HOURS_IN_DAY)).isEqualTo("2d5h46min");
+ assertThat(Duration.create(ONE_DAY_IN_MINUTES).encode(HOURS_IN_DAY)).isEqualTo("1d");
+ assertThat(Duration.create(ONE_HOUR_IN_MINUTES).encode(HOURS_IN_DAY)).isEqualTo("1h");
+ assertThat(Duration.create(HOURS_IN_DAY * ONE_HOUR_IN_MINUTES).encode(HOURS_IN_DAY)).isEqualTo("1d");
+ assertThat(Duration.create(ONE_MINUTE).encode(HOURS_IN_DAY)).isEqualTo("1min");
}
@Test
public void decode() throws Exception {
- assertThat(Duration.decode(" 15 d 26 h 42min ")).isEqualTo(Duration.create(15 * ONE_DAY_IN_MINUTES + 26 * ONE_HOUR_IN_MINUTES + 42 * ONE_MINUTE));
- assertThat(Duration.decode("26h15d42min")).isEqualTo(Duration.create(15 * ONE_DAY_IN_MINUTES + 26 * ONE_HOUR_IN_MINUTES + 42 * ONE_MINUTE));
- assertThat(Duration.decode("26h")).isEqualTo(Duration.create(26 * ONE_HOUR_IN_MINUTES));
- assertThat(Duration.decode("15d")).isEqualTo(Duration.create(15 * ONE_DAY_IN_MINUTES));
- assertThat(Duration.decode("42min")).isEqualTo(Duration.create(42 * ONE_MINUTE));
+ assertThat(Duration.decode(" 15 d 26 h 42min ", HOURS_IN_DAY)).isEqualTo(Duration.create(15 * ONE_DAY_IN_MINUTES + 26 * ONE_HOUR_IN_MINUTES + 42 * ONE_MINUTE));
+ assertThat(Duration.decode("26h15d42min", HOURS_IN_DAY)).isEqualTo(Duration.create(15 * ONE_DAY_IN_MINUTES + 26 * ONE_HOUR_IN_MINUTES + 42 * ONE_MINUTE));
+ assertThat(Duration.decode("26h", HOURS_IN_DAY)).isEqualTo(Duration.create(26 * ONE_HOUR_IN_MINUTES));
+ assertThat(Duration.decode("15d", HOURS_IN_DAY)).isEqualTo(Duration.create(15 * ONE_DAY_IN_MINUTES));
+ assertThat(Duration.decode("42min", HOURS_IN_DAY)).isEqualTo(Duration.create(42 * ONE_MINUTE));
}
@Test
public void fail_to_decode_if_not_number() throws Exception {
try {
- Duration.decode("Xd");
+ Duration.decode("Xd", HOURS_IN_DAY);
fail();
} catch (Exception e) {
- assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("'Xd' is invalid, it should use the following sample format : 2d 10h 15min");
+ assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("Duration 'Xd' is invalid, it should use the following sample format : 2d 10h 15min");
}
}
@Test
- public void convert_to_minutes_with_given_hours_in_day() throws Exception {
- assertThat(Duration.create(2 * ONE_DAY_IN_MINUTES).toMinutes(8)).isEqualTo(2 * 8 * ONE_HOUR_IN_MINUTES);
- assertThat(Duration.create(2 * ONE_HOUR_IN_MINUTES).toMinutes(8)).isEqualTo(2 * ONE_HOUR_IN_MINUTES);
- assertThat(Duration.create(2 * ONE_MINUTE).toMinutes(8)).isEqualTo(2 * ONE_MINUTE);
+ public void is_greater_than() throws Exception {
+ assertThat(Duration.decode("1h", HOURS_IN_DAY).isGreaterThan(Duration.decode("1min", HOURS_IN_DAY))).isTrue();
+ assertThat(Duration.decode("1min", HOURS_IN_DAY).isGreaterThan(Duration.decode("1d", HOURS_IN_DAY))).isFalse();
+ assertThat(Duration.decode("1d", HOURS_IN_DAY).isGreaterThan(Duration.decode("1d", HOURS_IN_DAY))).isFalse();
+ assertThat(Duration.decode("1d", 10).isGreaterThan(Duration.decode("1d", 8))).isTrue();
}
@Test