简体   繁体   English

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

[英]NumberFormat incorrect parse for non default locale in java

NumberFormat is incorrectly parsing a number for locale other than the default en_US. NumberFormat错误地解析了默认en_US以外的语言环境的数字。 For example parsing for fr_CA gives incorrect results. 例如对于fr_CA解析给出不正确的结果。

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

Output is: 2.302 输出为: 2.302

Expected output: 2302,52 or 2302.52 预期输出: 2302,522302.52

It is basically changing the value of this number from 2 thousands something to just 2 something, which is incorrect. 基本上是将此数字的值从2000个更改为2个,这是不正确的。

See the below screenshot for details: 有关详细信息,请参见以下屏幕截图: 在此处输入图片说明

What is going wrong I'm unable to identify, please help ! 发生了什么问题,我无法确定,请帮忙!

EDIT 1: 编辑1:

I was able to use DecimalFormat to correctly parse non default locale values by setting the decimal and grouping separator as: 通过将小数和分组分隔符设置为,我能够使用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;

But I really want to be able to do this dynamically at run time without having to set the separators for each language/country combination I might receive. 但我真的希望能够在运行时动态地执行此操作,而不必为可能收到的每种语言/国家/地区组合设置分隔符。 Please help with any suggestions. 请帮助任何建议。

EDIT 2: 编辑2:

I ended up with the following final code to be able to dynamically parse and format localized values. 我最终得到了以下最终代码,以便能够动态解析和格式化本地化的值。 This works for patterns like ###,###.## and ###.###,## - assumptions being - 这适用于###,###。##和###。###,##等模式-假设是-

  1. there are always only 2 decimal places in the data received 接收到的数据中始终只有2个小数位
  2. decimal separator is either a comma or a period 小数点分隔符可以是逗号或句点
  3. grouping separator is either a period or a comma 分组分隔符可以是句点或逗号

     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); */ 

Needless to say I'm not satisfied with the solution, which is more of a workaround until I get a solution to the main problem - NumberFormat incorrect parse for non default locale. 不用说,我对解决方案不满意,这更多的是一种变通办法,直到我解决主要问题-非默认语言环境的NumberFormat错误解析。 Therefore any hints, suggestions, solutions are still welcome. 因此,仍然欢迎任何提示,建议和解决方案。

You have 2 problems here, 这里有两个问题

1) You're creating the locale incorrectly. 1)您创建的语言环境不正确。 Use Locale.CANADA_FRENCH . 使用Locale.CANADA_FRENCH

2) The given number is invalid in both the default and Canadian locales. 2)给定的号码在默认语言环境和加拿大语言环境中均无效。 As per ICU , in fr_CA , the grouping separator is empty, and the decimal separator is , . 按照ICU ,在fr_CA ,分组分离器是空的,并且小数点分隔符是,

As such, in your example, that uses the default locale, it treats . 因此,在您的示例中,使用默认语言环境,它会处理. as a decimal separator and bails at , , where as in the correct locale it will bail at . 作为小数点分隔符,并在横木,其中在正确的区域设置,将在保释. and return simply 2 . 然后简单地返回2

The correct way to write this number in fr_CA is 2302,52 fr_CA写入此数字的正确方法是2302,52

So, really, Java is correct, but your assumption on the format of this number is incorrect. 因此,实际上,Java是正确的,但是您对此数字格式的假设是不正确的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM