]> granicus.if.org Git - icu/commitdiff
ICU-10970 Support decimal point required
authorScott Russell <DTownSMR@gmail.com>
Sat, 30 Aug 2014 23:12:15 +0000 (23:12 +0000)
committerScott Russell <DTownSMR@gmail.com>
Sat, 30 Aug 2014 23:12:15 +0000 (23:12 +0000)
X-SVN-Rev: 36301

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

index 7abba4e40aeceb5c717429f0c6692c65f3f704e6..d5aaa05d1637c3f12065e1213234738cb06aacfd 100644 (file)
@@ -2305,6 +2305,8 @@ public class DecimalFormat extends NumberFormat {
         "com.ibm.icu.text.DecimalFormat.SkipExtendedSeparatorParsing", "false")
         .equals("true");
 
+    // allow control of requiring a matching decimal point when parsing
+    boolean parseRequireDecimalPoint = false;
 
     // When parsing a number with big exponential value, it requires to transform the
     // value into a string representation to construct BigInteger instance.  We want to
@@ -2628,6 +2630,14 @@ public class DecimalFormat extends NumberFormat {
                 }
             }
 
+            if(digits.decimalAt == 0 && isDecimalPatternMatchRequired()) {
+                if(this.formatPattern.indexOf(decimal) != -1) {
+                    parsePosition.setIndex(oldStart);
+                    parsePosition.setErrorIndex(position);
+                    return false;
+                }
+            }
+            
             if (backup != -1)
                 position = backup;
 
@@ -3766,6 +3776,31 @@ public class DecimalFormat extends NumberFormat {
     public boolean isDecimalSeparatorAlwaysShown() {
         return decimalSeparatorAlwaysShown;
     }
+    
+    /**
+     * When decimal match is not required, the input does not have to
+     * contain a decimal mark when there is a decimal mark specified in the
+     * pattern. 
+     * @param value true if input must contain a match to decimal mark in pattern  
+     * Default is false.
+     * @draft ICU 54
+     * @provisional This API might change or be removed in a future release.
+     */
+     public void setDecimalPatternMatchRequired(boolean value) {
+         parseRequireDecimalPoint = value;
+     }
+
+    /**
+     * {@icu} Returns whether the input to parsing must contain a decimal mark if there
+     * is a decimal mark in the pattern.
+     * @return true if input must contain a match to decimal mark in pattern
+     * @draft ICU 54
+     * @provisional This API might change or be removed in a future release.
+     */
+    public boolean isDecimalPatternMatchRequired() {
+        return parseRequireDecimalPoint;
+    }
+
 
     /**
      * Sets the behavior of the decimal separator with integers. (The decimal separator
index df67d0499b617520d7988f10a370545111f3b24a..8db671984b99a4238a50dd55d17b35ed1a6b7393 100644 (file)
@@ -3682,4 +3682,41 @@ public class NumberFormatTest extends com.ibm.icu.dev.test.TestFmwk {
             assertEquals("Test Currency Context", TWD_changed_expected, TWD_changed);
         }
     }
+
+    public void TestParseRequiredDecimalPoint() {
+        
+        String[] testPattern = { "00.####", "00.0", "00" };
+        
+        String value2Parse = "99";
+        double parseValue  =  99;
+        DecimalFormat parser = new DecimalFormat();
+        double result;
+        boolean hasDecimalPoint; 
+        for (int i = 0; i < testPattern.length; i++) {            
+            parser.applyPattern(testPattern[i]);
+            hasDecimalPoint = testPattern[i].contains(".");
+            
+            parser.setDecimalPatternMatchRequired(false);
+            try {
+                result = parser.parse(value2Parse).doubleValue();
+                assertEquals("wrong parsed value", parseValue, result);
+            } catch (ParseException e) {
+               this.errln("Parsing " + value2Parse + " should have succeeded with " + testPattern[i] + 
+                            " and isDecimalPointMatchRequired set to: " + parser.isDecimalPatternMatchRequired());
+            }
+            
+            parser.setDecimalPatternMatchRequired(true);
+            try {
+                result = parser.parse(value2Parse).doubleValue();
+                if(hasDecimalPoint){
+                    this.errln("Parsing " + value2Parse + " should NOT have succeeded with " + testPattern[i] + 
+                            " and isDecimalPointMatchRequired set to: " + parser.isDecimalPatternMatchRequired());
+                }
+            } catch (ParseException e) {
+                    // OK, should fail
+            }
+        }
+        
+    }
+    
 }