将货币舍入到最近的美元,你是怎么做到的?

时间:2012-10-19 02:57:04

标签: android exception currency rounding

以下代码适用于我的制作应用中的所有手机,但运行4.1.2的Galaxy Nexus除外。 Play商店向我发送了错误,我将首先发布代码,然后是错误:

    // Roughly formats the currency by loping off the decimal places (amount
// comes already rounded)
public static String formatCurrencyRound(double amount) {
    String currency = formatCurrency(amount); // Returns "$8.00"

    return currency.substring(0, currency.indexOf("."));
}

错误:

java.lang.RuntimeException: Unable to resume activity {com.ootpapps.saving.made.simple/com.ootpapps.saving.made.simple.SavingsPlanOverview}: java.lang.StringIndexOutOfBoundsException: length=9; regionStart=0; regionLength=-1
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2575)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2603)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2089)
at android.app.ActivityThread.access$600(ActivityThread.java:130)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.StringIndexOutOfBoundsException: length=9; regionStart=0; regionLength=-1
at java.lang.String.startEndAndLength(String.java:593)
at java.lang.String.substring(String.java:1474)
at com.ootpapps.saving.made.simple.App.formatCurrencyRound(App.java:68)
at com.ootpapps.saving.made.simple.SavingsPlanOverview.updateSavingsPlanWidgets(SavingsPlanOverview.java:224)
at com.ootpapps.saving.made.simple.SavingsPlanOverview.onResume(SavingsPlanOverview.java:156)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1184)
at android.app.Activity.performResume(Activity.java:5082)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2565)
... 12 more

如果有人可以提出更好的方法来舍入这个货币字符串,或者更好的方法将原始数字舍入到没有小数的格式化字符串中,我会非常感激。而且,由于某种原因,这只会在运行4.1.2的GNexus上失败。

谢谢!

编辑已添加的格式货币代码:

public static String formatCurrency(double amount) {
    NumberFormat currency = NumberFormat.getCurrencyInstance();

    return currency.format(amount);
}

编辑续 - 我用的代码可以将货币换成全元

public static String formatCurrencyWhole(double amount) {
    NumberFormat currency = NumberFormat.getCurrencyInstance();
    currency.setMaximumFractionDigits(0);
    currency.setMinimumFractionDigits(0);

    return currency.format(amount);
}

2 个答案:

答案 0 :(得分:2)

首先,货币永远不应该使用double处理永远 永远 。您应该使用BigDecimal来保持精确度。 (有关详细信息,请参阅this question。)

除此之外,您可以使用NumberFormat获取String代表:

NumberFormat format = NumberFormat.getCurrencyInstance(Locale.US);
String result = format.format(amount);

.format()需要一倍;如果您最终使用BigDecimal,请使用bigDecimal.doubleValue()This answer提供了该领域的一些其他详细信息。

答案 1 :(得分:2)

我认为字符串的格式已经是8美元

如果小数不存在:

currency.substring(0,currency.indexOf(“。”));

将抛出IndexOutOfBoundsException。

解决方案可能就像手前测试小数一样简单。

public static String formatCurrencyRound(double amount){     String currency = formatCurrency(amount); //返回“$ 8.00”

if(currency.indexOf(".") != -1){
   return currency.substring(0, currency.indexOf("."));
}else{
   return currency;
}

}

-------编辑----------

正如Ken(非常聪明的家伙)在评论中指出的,堆栈跟踪中的关键行是:

java.lang.StringIndexOutOfBoundsException:length = 9; regionStart = 0; regionLength = -1 在java.lang.String.startEndAndLength(String.java:593)

此错误显示regionLength = -1,表示indexOf(“。”)的结果为-1。 ((“。”)不存在)

它还显示字符串长度为9,这使我认为不同的分隔符问题(Ken也指出)可能是真正的问题。除非美元金额在$ 10000000范围内。

这就是为什么我想看看formatCurrency(Double);

的代码

- - - - - - - - 编辑

怀疑您使用的是默认语言环境:

NumberFormat currency = NumberFormat.getCurrencyInstance();

文档说明了这一点:

http://developer.android.com/reference/java/util/Locale.html

  

“默认语言环境不适合机器可读的输出。最好的选择通常是Locale.US - 这个语言环境保证在所有设备上都可用,并且它没有任何令人惊讶的特殊情况并经常出现使用(特别是用于计算机 - 计算机通信)意味着它也是最有效的选择。

     

一个常见的错误是在生成意味着机器可读的输出时隐式使用默认语言环境。这往往适用于开发人员的测试设备(特别是因为许多开发人员使用en_US),但在用户处于更复杂的语言环境的设备上运行时会失败。“

除非您的应用需要外币,否则请使用:

NumberFormat currency = NumberFormat.getCurrencyInstance(Locale.US);