]> granicus.if.org Git - icu/commitdiff
ICU-10640 Carry rounding measure amounts down except the last to the JAVA implementation.
authorTravis Keep <keep94@gmail.com>
Thu, 20 Feb 2014 18:54:00 +0000 (18:54 +0000)
committerTravis Keep <keep94@gmail.com>
Thu, 20 Feb 2014 18:54:00 +0000 (18:54 +0000)
X-SVN-Rev: 35182

icu4j/main/classes/core/src/com/ibm/icu/text/MeasureFormat.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/MeasureUnitTest.java

index 9b9313e4a7aef81212c8839ccb12bb11945034a7..166894ae3aae024fd4e62c7a24e4c95c2303e7c9 100644 (file)
@@ -31,6 +31,7 @@ import com.ibm.icu.impl.DontCareFieldPosition;
 import com.ibm.icu.impl.ICUResourceBundle;
 import com.ibm.icu.impl.SimpleCache;
 import com.ibm.icu.impl.SimplePatternFormatter;
+import com.ibm.icu.math.BigDecimal;
 import com.ibm.icu.util.Currency;
 import com.ibm.icu.util.CurrencyAmount;
 import com.ibm.icu.util.Measure;
@@ -121,6 +122,8 @@ public class MeasureFormat extends UFormat {
     private final transient NumericFormatters numericFormatters;
     
     private final transient ImmutableNumberFormat currencyFormat;
+    
+    private final transient ImmutableNumberFormat integerFormat;
 
     private static final SimpleCache<ULocale,Map<MeasureUnit, EnumMap<FormatWidth, QuantityFormatter>>> localeToUnitToStyleToCountToFormat
             = new SimpleCache<ULocale,Map<MeasureUnit, EnumMap<FormatWidth, QuantityFormatter>>>();
@@ -247,7 +250,10 @@ public class MeasureFormat extends UFormat {
                 localeToNumericDurationFormatters.put(locale, formatters);
             }
         }
-        
+        NumberFormat intFormat = NumberFormat.getInstance(locale);
+        intFormat.setMaximumFractionDigits(0);
+        intFormat.setMinimumFractionDigits(0);
+        intFormat.setRoundingMode(BigDecimal.ROUND_DOWN);
         return new MeasureFormat(
                 locale,
                 formatWidth,
@@ -256,7 +262,8 @@ public class MeasureFormat extends UFormat {
                 unitToStyleToCountToFormat,
                 formatters,
                 new ImmutableNumberFormat(
-                        NumberFormat.getInstance(locale, formatWidth.getCurrencyStyle())));
+                        NumberFormat.getInstance(locale, formatWidth.getCurrencyStyle())),
+                new ImmutableNumberFormat(intFormat));
     }
     
     /**
@@ -297,7 +304,7 @@ public class MeasureFormat extends UFormat {
         } else if (obj instanceof Measure[]) {
             toAppendTo.append(formatMeasures(new StringBuilder(), fpos, (Measure[]) obj));
         } else if (obj instanceof Measure){
-            toAppendTo.append(formatMeasure((Measure) obj, new StringBuilder(), fpos));
+            toAppendTo.append(formatMeasure((Measure) obj, numberFormat, new StringBuilder(), fpos));
         } else {
             throw new IllegalArgumentException(obj.toString());            
         }
@@ -362,7 +369,7 @@ public class MeasureFormat extends UFormat {
             return appendTo;
         }
         if (measures.length == 1) {
-            return formatMeasure(measures[0], appendTo, fieldPosition);
+            return formatMeasure(measures[0], numberFormat, appendTo, fieldPosition);
         }
         
         if (formatWidth == FormatWidth.NUMERIC) {
@@ -382,7 +389,9 @@ public class MeasureFormat extends UFormat {
         // Fast track: No field position.
         String[] results = new String[measures.length];
         for (int i = 0; i < measures.length; i++) {
-            results[i] = formatMeasure(measures[i]);
+            results[i] = formatMeasure(
+                    measures[i],
+                    i == measures.length - 1 ? numberFormat : integerFormat);
         }
         return appendTo.append(listFormatter.format((Object[]) results));                 
        
@@ -482,7 +491,8 @@ public class MeasureFormat extends UFormat {
                 this.rules,
                 this.unitToStyleToCountToFormat,
                 this.numericFormatters,
-                this.currencyFormat);
+                this.currencyFormat,
+                this.integerFormat);
     }
     
     private MeasureFormat(
@@ -492,7 +502,8 @@ public class MeasureFormat extends UFormat {
             PluralRules rules,
             Map<MeasureUnit, EnumMap<FormatWidth, QuantityFormatter>> unitToStyleToCountToFormat,
             NumericFormatters formatters,
-            ImmutableNumberFormat currencyFormat) {
+            ImmutableNumberFormat currencyFormat,
+            ImmutableNumberFormat integerFormat) {
         setLocale(locale, locale);
         this.formatWidth = formatWidth;
         this.numberFormat = format;
@@ -500,6 +511,7 @@ public class MeasureFormat extends UFormat {
         this.unitToStyleToCountToFormat = unitToStyleToCountToFormat;
         this.numericFormatters = formatters;
         this.currencyFormat = currencyFormat;
+        this.integerFormat = integerFormat;
     }
     
     MeasureFormat() {
@@ -510,6 +522,7 @@ public class MeasureFormat extends UFormat {
         this.unitToStyleToCountToFormat = null;
         this.numericFormatters = null;
         this.currencyFormat = null;
+        this.integerFormat = null;
     }
     
     static class NumericFormatters {
@@ -601,14 +614,17 @@ public class MeasureFormat extends UFormat {
         return unitToStyleToCountToFormat;
     }
     
-    private String formatMeasure(Measure measure) {
+    private String formatMeasure(Measure measure, ImmutableNumberFormat nf) {
         return formatMeasure(
-                measure, new StringBuilder(),
+                measure, nf, new StringBuilder(),
                 DontCareFieldPosition.INSTANCE).toString();
     }
     
     private StringBuilder formatMeasure(
-            Measure measure, StringBuilder appendTo, FieldPosition fieldPosition) {
+            Measure measure,
+            ImmutableNumberFormat nf,
+            StringBuilder appendTo,
+            FieldPosition fieldPosition) {
         if (measure.getUnit() instanceof Currency) {
             return appendTo.append(
                     currencyFormat.format(
@@ -620,7 +636,7 @@ public class MeasureFormat extends UFormat {
         Number n = measure.getNumber();
         MeasureUnit unit = measure.getUnit(); 
         UFieldPosition fpos = new UFieldPosition(fieldPosition.getFieldAttribute(), fieldPosition.getField());
-        StringBuffer formattedNumber = numberFormat.format(n, new StringBuffer(), fpos);
+        StringBuffer formattedNumber = nf.format(n, new StringBuffer(), fpos);
         String keyword = rules.select(new PluralRules.FixedDecimal(n.doubleValue(), fpos.getCountVisibleFractionDigits(), fpos.getFractionDigits()));
 
         Map<FormatWidth, QuantityFormatter> styleToCountToFormat = unitToStyleToCountToFormat.get(unit);
@@ -705,13 +721,14 @@ public class MeasureFormat extends UFormat {
         
         int fieldPositionFoundIndex = -1;
         for (int i = 0; i < measures.length; ++i) {
+            ImmutableNumberFormat nf = (i == measures.length - 1 ? numberFormat : integerFormat);
             if (fieldPositionFoundIndex == -1) {
-                results[i] = formatMeasure(measures[i], new StringBuilder(), fpos).toString();
+                results[i] = formatMeasure(measures[i], nf, new StringBuilder(), fpos).toString();
                 if (fpos.getBeginIndex() != 0 || fpos.getEndIndex() != 0) {
                     fieldPositionFoundIndex = i;    
                 }
             } else {
-                results[i] = formatMeasure(measures[i]);
+                results[i] = formatMeasure(measures[i], nf);
             }
         }
         ListFormatter.FormattedListBuilder builder =
index 84af67f6b5961ec9bcea0ca3c7d5bb6972471a56..abd6c2f0ebce67fa6c0074c6c879790cd4ab30dd 100644 (file)
@@ -575,6 +575,29 @@ public class MeasureUnitTest extends TestFmwk {
         assertEquals("getWidth", MeasureFormat.FormatWidth.WIDE, mf.getWidth());
     }
     
+    public void testDoubleZero() {
+        ULocale en = new ULocale("en");
+        NumberFormat nf = NumberFormat.getInstance(en);
+        nf.setMinimumFractionDigits(2);
+        nf.setMaximumFractionDigits(2);
+        MeasureFormat mf = MeasureFormat.getInstance(en, FormatWidth.WIDE, nf);
+        assertEquals(
+                "Positive Rounding",
+                "4 hours, 23 minutes, 16.00 seconds",
+                mf.formatMeasures(
+                        new Measure(4.7, MeasureUnit.HOUR),
+                        new Measure(23, MeasureUnit.MINUTE),
+                        new Measure(16, MeasureUnit.SECOND)));
+        assertEquals(
+                "Negative Rounding",
+                "-4 hours, 23 minutes, 16.00 seconds",
+                mf.formatMeasures(
+                        new Measure(-4.7, MeasureUnit.HOUR),
+                        new Measure(23, MeasureUnit.MINUTE),
+                        new Measure(16, MeasureUnit.SECOND)));
+        
+    }
+    
     static void generateCXXHConstants() {
         Map<String, MeasureUnit> seen = new HashMap<String, MeasureUnit>();
         TreeMap<String, List<MeasureUnit>> allUnits = new TreeMap<String, List<MeasureUnit>>();