6

EditTextユーザーが45.60(アメリカドルの例)のような数字を入力できるようにする単純ながあります。次に、次の方法を使用してこの数値をフォーマットします。

public String format() {
    NumberFormat formatter = NumberFormat.getCurrencyInstance(Locale.getDefault());
    return formatter.format(amount.doubleValue());
}

また、私の Android フォンでは、言語が英語 (米国) に設定されているためLocale.getDefault()、米国のロケールが返されるはずです (実際に返されます)。

編集テキストが次のように正しく更新されるようになりました$45.60(したがって、入力した数値の書式設定が機能します)。

"$45.60"ただし、次の方法を使用して上記の文字列を解析しようとすると:

NumberFormat numberFormat = NumberFormat.getInstance(Locale.getDefault());
Number result = numberFormat.parse("$45.60");

次のエラーで失敗します。

java.lang.IllegalArgumentException: Failed to parse amount $45.60 using locale en_US.

携帯電話を英語/英国に設定すると、これ"45.60""£45.60"正しく機能するように書式設定されますが (米国の場合と同様) "£45.60"、上記の米国のサンプルと同様に解析に失敗します。

ただし、電話をドイツ語 (ドイツ) に設定すると、書式設定"45,60""45,60€"正しく機能し、解析"45,60€"も正しく機能します!

これら 3 つの通貨の唯一の違いは、ユーロが金額に追加され、ドルとポンドが金額の前に追加されることです。

同じコードがユーロでは機能するのに、ポンドとドルでは機能しない理由を知っている人はいますか? 何か不足していますか?

問題を再現するために、単体テストも作成しました。

public void testCreateStringBased() throws Exception {

    // For German locale
    CurrencyAmount amount = new CurrencyAmount("25,46€", Locale.GERMANY);
    assertEquals(25.46, amount.getAsDouble());

    // For French locale
    amount = new CurrencyAmount("25,46€", Locale.FRANCE);
    assertEquals(25.46, amount.getAsDouble());

    // For US locale
    amount = new CurrencyAmount("$25.46", Locale.US);
    assertEquals(25.46, amount.getAsDouble());

    // For UK locale
    amount = new CurrencyAmount("£25.46", Locale.UK);
    assertEquals(25.46, amount.getAsDouble());
}

CurrencyAmount基本的に、通貨文字列を解析するために投稿したコードをラップしますが、デフォルトのロケールの代わりに特定のロケールを使用する点が異なります。上記の例では、テストは GERMANY および FRANCE ロケールでは成功しますが、US および UK ロケールでは失敗します。

4

6 に答える 6

7

これまでに提案された答えは問題を完全に解決しなかったので、私は痛々しいほどアマチュア的なアプローチを取りました:

String value = "$24,76" 
value = value.replace(getCurrencySymbol(locale), StringUtils.EMPTY);

NumberFormat numberFormat = NumberFormat.getInstance(locale);
Number result = numberFormat.parse(value);

だから今、私は単に文字列の値を通貨記号から取り除くだけです...このようにして、45.78または45,78または$45.78または45,78€などの必要なものすべてを処理できます...。

入力が何であれ、通貨記号は単純に削除され、単純な数字になります。これで、ユニットテスト(OPを参照)が正常に完了しました。

誰かがもっと良いものを思いついたら、私に知らせてください。

于 2013-03-23T13:48:42.697 に答える
3

以下を試してください:

NumberFormat numberFormat = new DecimalFormat("¤#.00", new DecimalFormatSymbols(Locale.UK));
numberFormat.parse("£123.5678");

¤ - 通貨記号。ロケールによる通貨記号との一致が期待されます。

リンクhttp://docs.oracle.com/javase/6/docs/api/java/text/DecimalFormat.htmlをたどることで見ることができる他のパターン記号

于 2013-03-23T12:55:59.503 に答える
1

NumberFormat.getInstance().parse() の代わりに NumberFormat.getCurrencyInstance().parse() を試してください。

于 2013-03-23T11:46:54.877 に答える
0

私はhttps://dzone.com/articles/currency-format-validation-andから適応した以下を使用しています

import java.math.BigDecimal;
import org.apache.commons.validator.routines.*;

BigDecimalValidator currencyValidator = CurrencyValidator.getInstance();
BigDecimal parsedCurrency = currencyValidator.validate(currencyString);
if ( parsedCurrency == null ) {
        throw new Exception("Invalid currency format (please also ensure it is UTF-8)");
}

ユーザーごとに正しいロケールが使用されていることを確認する必要がある場合は 、ログイン時にロケールを変更するを参照してください。

于 2016-06-29T20:17:58.803 に答える