diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/workingday/EffortDuration.java b/navalplanner-business/src/main/java/org/navalplanner/business/workingday/EffortDuration.java index ad9d252e6..bcdd5441e 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/workingday/EffortDuration.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/workingday/EffortDuration.java @@ -20,7 +20,9 @@ package org.navalplanner.business.workingday; +import java.math.BigDecimal; import java.util.EnumMap; +import java.util.Map.Entry; import org.apache.commons.lang.Validate; @@ -184,4 +186,16 @@ public class EffortDuration implements Comparable { return new EffortDuration(seconds - duration.seconds); } + public BigDecimal toHoursAsDecimalWithScale(int scale) { + BigDecimal result = BigDecimal.ZERO; + final BigDecimal secondsPerHour = new BigDecimal(3600); + for (Entry each : decompose().entrySet()) { + BigDecimal seconds = new BigDecimal(each.getKey().toSeconds( + each.getValue())); + result = result.add(seconds.divide(secondsPerHour, scale, + BigDecimal.ROUND_HALF_UP)); + } + return result; + } + } diff --git a/navalplanner-business/src/test/java/org/navalplanner/business/test/workingday/EffortDurationTest.java b/navalplanner-business/src/test/java/org/navalplanner/business/test/workingday/EffortDurationTest.java index 1bc0aaff3..e1fef0434 100644 --- a/navalplanner-business/src/test/java/org/navalplanner/business/test/workingday/EffortDurationTest.java +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/workingday/EffortDurationTest.java @@ -30,6 +30,7 @@ import static org.navalplanner.business.workingday.EffortDuration.hours; import static org.navalplanner.business.workingday.EffortDuration.minutes; import static org.navalplanner.business.workingday.EffortDuration.seconds; +import java.math.BigDecimal; import java.util.EnumMap; import org.junit.Test; @@ -161,4 +162,30 @@ public class EffortDurationTest { assertThat(hours(2).minus(minutes(60)), equalTo(hours(1))); } + @Test + public void canConvertToDecimalHours() { + EffortDuration duration = hours(1).and(30, Granularity.MINUTES); + assertThat(duration.toHoursAsDecimalWithScale(1), equalTo(new BigDecimal("1.5"))); + } + + @Test + public void theScaleIsTheOneProvided() { + EffortDuration duration = hours(1).and(30, Granularity.MINUTES); + assertThat(duration.toHoursAsDecimalWithScale(1).scale(), equalTo(1)); + assertThat(duration.toHoursAsDecimalWithScale(2).scale(), equalTo(2)); + assertThat(duration.toHoursAsDecimalWithScale(3).scale(), equalTo(3)); + } + + @Test + public void anHalfUpRoundIsDone() { + // 3601/3600 = 1.000277778 + EffortDuration duration = hours(1).and(1, Granularity.SECONDS); + assertThat(duration.toHoursAsDecimalWithScale(6), equalTo(new BigDecimal( + "1.000278"))); + assertThat(duration.toHoursAsDecimalWithScale(5), + equalTo(new BigDecimal("1.00028"))); + assertThat(duration.toHoursAsDecimalWithScale(4), + equalTo(new BigDecimal("1.0003"))); + } + }