NumberFormat对java中非默认语言环境的错误解析

时间:2017-10-05 05:21:12

标签: java locale number-formatting

NumberFormat错误地解析了默认en_US以外的区域设置的数字。例如,解析fr_CA会得到错误的结果。

NumberFormat nf = NumberFormat.getNumberInstance(new Locale("fr_CA"));
Number num = nf.parse("2.302,52");

输出为:2.302

预期输出:2302,522302.52

它基本上将这个数字的值从2千比特改为2比特,这是不正确的。

有关详细信息,请参阅以下屏幕截图: enter image description here

出了什么问题我无法识别,请帮忙!

2 个答案:

答案 0 :(得分:1)

编辑1:

通过将小数点和分组分隔符设置为:

,我能够使用DecimalFormat正确解析非默认语言环境值。

        /**
         * Testing DF parse
         */
        DecimalFormat df = new DecimalFormat();
        DecimalFormatSymbols symbols = new DecimalFormatSymbols();
        symbols.setDecimalSeparator(',');
        symbols.setGroupingSeparator('.');
        df.setDecimalFormatSymbols(symbols);
        Number num = df.parse("2.302,52"); // OUTPUT is: 2302.52 -> correctly parsed

        /**
         * Round off and format
         */
        double d = num.doubleValue();
        double roundedVal = Math.round(d); // OUTPUT is: 2303.0 -> correctly rounded off
        String localeAwareVlue = df.format(roundedVal); // OUTPUT is: 2.303 -> using correct grouping separator
        valueString = localeAwareVlue;

但是我真的希望能够在运行时动态地执行此操作,而不必为我可能会收到的每种语言/国家/地区组合设置分隔符。请提供任何建议。

编辑2:

我最终得到了以下最终代码,以便能够动态解析和格式化本地化值。这适用于###,###。##和###。###,##等模式-假设为-

  1. 接收到的数据中总是只有2位小数位
  2. 小数点分隔符是逗号或句点
  3. 分组分隔符可以是句点或逗号

    String localValue = args.get(0).toString();
    // String locale = args.get(1).toString();
    
    char decChar = localValue.charAt(localValue.length()-3);
    char grpChar = ',';
    if(decChar == ',') {
        grpChar = '.';
    }
    DecimalFormat df = new DecimalFormat();
    DecimalFormatSymbols symbols = new DecimalFormatSymbols();
    symbols.setDecimalSeparator(decChar);
    symbols.setGroupingSeparator(grpChar);
    df.setDecimalFormatSymbols(symbols);
    
    Number parsedValue = 0;
    try {
        parsedValue = df.parse(localValue);
    }
    catch (ParseException pe) {
        pe.printStackTrace();
    }
    
    /**
     * Round off and format to localize
     */
    double roundedValue = Math.round(parsedValue.doubleValue());
    String localeAwareValue = df.format(roundedValue);
    
    
    // TODO - use Locale with nf instead of above method
    // currently facing issue with incorrect parse for non default locale
    /*
       NumberFormat nf = NumberFormat.getInstance(new Locale(locale));
       Number num = nf.parse(localValue);
    */
    

不用说我对解决方案不满意,这更多的是一种变通办法,直到我解决主要问题-非默认语言环境的NumberFormat错误解析。因此,仍然欢迎任何提示,建议和解决方案。

答案 1 :(得分:0)

您在这里有2个问题,

1)您创建的语言环境不正确。使用Locale.CANADA_FRENCH

2)给定的数字在默认语言环境和加拿大语言环境中均无效。根据{{​​3}},在fr_CA中,分组分隔符为空,十进制分隔符为,

因此,在您的示例中,使用默认语言环境,它将.视为小数分隔符,并在,下保释,在正确的语言环境中,它将在{{1}处保释。 },然后仅返回.

2中写这个数字的正确方法是fr_CA

实际上,Java是正确的,但是您对此数字格式的假设是错误的。