【问题标题】:Best way to convert Locale specific String to BigDecimal将特定于语言环境的字符串转换为 BigDecimal 的最佳方法
【发布时间】:2012-10-11 09:41:58
【问题描述】:

我必须将格式为 String 的德语语言环境转换为 BigDecimal。但是,我正在努力寻找最佳解决方案。

以下代码显示了我的问题:

    String numberString = "2.105,88";

    NumberFormat nf = NumberFormat.getInstance(Locale.GERMAN);
    try {
        Number parsed = nf.parse(numberString);
        BigDecimal bd1 = new BigDecimal(parsed.toString());
        System.out.println(bd1.toString());

        BigDecimal bd2 = new BigDecimal(parsed.doubleValue());
        System.out.println(bd2);

        BigDecimal bd3 = new BigDecimal(numberString);
        System.out.println(bd3);

    } catch (ParseException e) {
        e.printStackTrace();
    }

这个输出是

2105.88

2105.8800000000001091393642127513885498046875

线程“main”中的异常 java.lang.NumberFormatException 在 java.math.BigDecimal.(未知来源) 在 java.math.BigDecimal.(未知来源) 在 test.BigDecimalTest.main(BigDecimalTest.java:22)

第一个输出是正确的,但是将String 转换为Number(准确地说是Double)然后再转换回String 然后再转换为特定的NumberBigDecimal 的类型。

第二个输出不正确,但可以通过设置BigDecimal的比例来解决。但是,位数并不总是已知的。

第三个输出显然不是我想要的。

我的问题:最好的方法是什么?有没有更好的方法来做到这一点?

【问题讨论】:

    标签: java bigdecimal


    【解决方案1】:

    似乎没有其他方法,因为java.Lang.Number 没有返回BigDecimal 类型的方法。无论如何,这是有道理的,因为BigDecimal 只接受格式正确的字符串,不像"2.105,88",而是像"2105.88"

    让我展示一下我的代码:

    import java.math.BigDecimal;
    import java.text.DecimalFormat;
    import java.text.NumberFormat;
    import java.text.ParseException;
    import java.util.Locale;
    public class JavaMain {
        public static void main(String[] args) {
            String numberString = "2.105,88";
            //using casting
            try {
                DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(Locale.GERMAN);
                df.setParseBigDecimal(true);
                BigDecimal bd = (BigDecimal) df.parseObject(numberString);
                System.out.println(bd.toString());
            } catch (ParseException e) {
                e.printStackTrace();
            }
            //your way short version
            NumberFormat nf = NumberFormat.getInstance(Locale.GERMAN);
            try {
                BigDecimal bd1 = new BigDecimal(nf.parse(numberString).toString());
                System.out.println(bd1.toString());
            } catch (ParseException e) {
                e.printStackTrace();
            }
            String numberStringFixed = "2105.88";
            //direct string formatted
            System.out.println(new BigDecimal(numberStringFixed));;     
            //direct but erroneous way if the string is not formatted
            System.out.println(new BigDecimal(numberString));;
            
        }
    }
    

    我希望这会有所帮助!

    【讨论】:

    • 至于“正确格式化”...2.105,88 实际上在一堆语言环境中完全正确格式化...在这些语言环境中,2105.88 根本不正确。这整个考验需要的是 BigDecimal 构造函数的 Locale 参数......
    【解决方案2】:

    DecimalFormat 有一个名为setParseBigDecimal 的方法,它导致parse() 返回BigDecimal。你只需要转换返回的Number

        String numberString = "2.105,88";
    
        NumberFormat nf = NumberFormat.getInstance(Locale.GERMAN);
        if (nf instanceof DecimalFormat) {
            DecimalFormat df = (DecimalFormat) nf;
            df.setParseBigDecimal(true);
            BigDecimal parsed = (BigDecimal) df.parse(numberString);
    
            System.out.println(parsed);
        }
    

    输出:

    2105.88

    setParseBigDecimal 是在 Java 1.5 中引入的。

    【讨论】:

    • @JarettMillard 其实DecimalFormat 有,NumberFormat 没有这个方法
    • @deFreitas NumberFormat 是一个抽象类。 DecimalFormat 的文档明确告诉您使用 NumberFormat.getInstance() 创建它的实例。
    • "NumberFormat 是一个抽象类",它没有这样的方法,这意味着您必须将工厂方法的结果转换回 DecimalFormat。
    猜你喜欢
    • 1970-01-01
    • 2016-05-02
    • 1970-01-01
    • 1970-01-01
    • 2021-01-27
    • 1970-01-01
    • 2022-01-26
    • 2014-06-21
    • 1970-01-01
    相关资源
    最近更新 更多