Add method for rounding to hours

FEA: ItEr60S19TimeUnitDataType
This commit is contained in:
Óscar González Fernández 2010-09-06 13:04:22 +02:00
parent 6f167388ae
commit 08306eba0b
2 changed files with 57 additions and 0 deletions

View file

@ -198,4 +198,39 @@ public class EffortDuration implements Comparable<EffortDuration> {
return result;
}
/**
* <p>
* Converts this duration in a number of hours. Uses a typical half up
* round, so for example one hour and half is converted to two hours. There
* is an exception though, when the duration is less than one hour and is
* not zero it's returned one. This is handy for avoiding infinite loops in
* some algorithms; when all code is converted to use {@link EffortDuration
* Effort Durations} this will no longer be necessary.
* </p>
* So there are three cases:
* <ul>
* <li>the duration is zero, 0 is returned</li>
* <li>if duration > 0 and duration < 1, 1 is returned</li>
* <li>if duration >= 1, typical half up round is done. For example 1 hour
* and 20 minutes returns 1 hour, 1 hour and 30 minutes 2 hours</li>
* </ul>
*
* @return an integer number of hours
*/
public int roundToHours() {
if (this.isZero()) {
return 0;
}
return Math.max(1, roundHalfUpToHours(this.decompose()));
}
private static int roundHalfUpToHours(
EnumMap<Granularity, Integer> components) {
int seconds = components.get(Granularity.SECONDS);
int minutes = components.get(Granularity.MINUTES)
+ (seconds < 30 ? 0 : 1);
int hours = components.get(Granularity.HOURS) + (minutes < 30 ? 0 : 1);
return hours;
}
}

View file

@ -188,4 +188,26 @@ public class EffortDurationTest {
equalTo(new BigDecimal("1.0003")));
}
@Test
public void theDurationCanBeRoundedToIntegerHours() {
assertThat(hours(0).roundToHours(), equalTo(0));
assertThat(hours(1).roundToHours(), equalTo(1));
assertThat(hours(2).roundToHours(), equalTo(2));
}
@Test
public void theTypeOfRoundDoneIsHalfUpWhenTheHoursAreAtLeastOne() {
assertThat(hours(1).and(20, Granularity.MINUTES).roundToHours(),
equalTo(1));
assertThat(hours(1).and(30, Granularity.MINUTES).roundToHours(),
equalTo(2));
}
@Test
public void ifDurationNotZeroIsAlwaysRoundedToAtLeastOne() {
assertThat(seconds(1).roundToHours(), equalTo(1));
assertThat(minutes(29).roundToHours(), equalTo(1));
assertThat(minutes(30).roundToHours(), equalTo(1));
}
}