NumberFormat.getCurrencyInstance();失败

Posted

技术标签:

【中文标题】NumberFormat.getCurrencyInstance();失败【英文标题】:NumberFormat.getCurrencyInstance(); Failure 【发布时间】:2013-02-13 16:19:07 【问题描述】:

我正在尝试使用 NumberFormat.getCurrencyInstance(); 将我的货币字符串解析为大十进制;

The following scenario
$1,000.01 Pass
1000.01 Pass
1,000.01 Fail -> This needs to be parsed to 1000.01 in order to pass.
abc Fail -> correct behavior. 

我的方法

   public BigDecimal parseClient(Field field, String clientValue, String message) throws ValidationException 
        if (clientValue == null) 
            return null;
        

        NumberFormat nf = NumberFormat.getCurrencyInstance();
        try 
            return new BigDecimal(nf.parse(clientValue).toString());
         catch (ParseException ex) 
            throw new ValidationException(message);
        
    

有谁知道让它正常工作的好解决方案?

【问题讨论】:

【参考方案1】:

这是相当蛮力的,但为什么不检查字符串开头是否存在货币字符,如果不存在,则添加它?

if ( !clientValue.startsWith( "$" ) )

   clientValue = "$" + clientValue;

如果不需要蛮力方法,则下一个方法是记录客户端可以进入该方法的每种格式。然后,创建处理这些传入输入格式所需的尽可能多的 DecimcalFormat 实例,并允许对它们进行解析。

另一种方法是将传入的 clientValue 标准化为单一格式。这可以通过字符串操作和正则表达式来完成。但是,您仍然有一个问题,您需要了解传入的 clientvalue 可以进入方法的所有不同方式。所以需求在这里非常重要。

【讨论】:

如果其他方法都失败了,那是我的解决方案,我只是不确定是否有更优雅的解决方案。 嗯,关于十进制格式(以及日期格式)的一点是,它们对于所有可能的排列都不是故障安全的。例如,负货币呢?有几种表达方式。如果负数出现在数字之前或之后怎么办?对于这样的事情,你真的必须尝试标准化输入的输入。而不是允许一种免费的方法来解析值。 @George 另一种可能的方法是尝试使用几个不同的 DecimalFormats 解析传入的值。显然,使用您编写的代码,传入的值不仅可以是货币格式,还可以是标准的数字十进制格式。 好点,我完全忽略了这种情况。你对此有什么建议吗?我只是想在插入数据库之前将客户端字符串转换为 bigdecimal。 没错,数字和货币都是合适的。我现在只是不确定如何处理负值。【参考方案2】:

尝试使用此构造函数:

public static NumberFormat getCurrencyInstance(Locale inLocale)

【讨论】:

我将构造函数设置为 Locale.US ,但它似乎仍然失败。

以上是关于NumberFormat.getCurrencyInstance();失败的主要内容,如果未能解决你的问题,请参考以下文章