2012-04-13 23 views
1

多くの文書を生成するシステムがあります。その内容はResourceBundlesで定義されています。ICU4JのMessageFormatで通貨書式をカスタマイズする方法

MessageFormatが通貨値を印刷する方法をカスタマイズしたいと考えています。ときには、小数点のない通貨(常にではない)を表示することがあります。

予想通りこれは動作するはずですが、それはありません:

System.err.println(
    com.ibm.icu.text.MessageFormat.format(
     "{0,number,\u00A4#}", 
     new com.ibm.icu.util.CurrencyAmount(1, 
     com.ibm.icu.util.Currency.getInstance("USD")))); 

残念ながら、それが出て出力します。

US$1,00 

はあなたの誰もが、リソース・バンドル「プロパティ」ファイル内の通貨のカスタム書式を使用しています?

私はシステム全体を変更したくありません。

そして、これはjava.text.MessageFormatでうまく動作します。

+0

JDKのバージョンを使用できない理由は何ですか?ところで、 'NumberFormat.getCurrencyInstance(locale)'を使用できない特別な理由はありますか? –

+0

ICUを使用する理由は2つあります。まず、JDKバージョンでは不可能な異なるロケールで特定の通貨を印刷する必要があります(通貨は現在のロケールで独立している必要があります)。また、ICUには異なるロケールでも印刷する必要のあるスペルアウト書式があります。私のすべてのメッセージはResourceBundleにあるので、私は 'NumberFormat.getCurrencyInstance(locale)'を使用したくありません。 – Marti

答えて

1

よろしくお願いいたします。 セントの一部を切り詰めたい理由は本当に分かりません(米国では、韓国や日本ではまったく使用しないので意味があります)。
とにかくセントの部分をカットするのは良い考えではないと思いますが、もしそれをしたいのであれば、NumberFormatをsetMaximumIntegerDigits(int)で使うのと同じくらい簡単です。

私はまだ、リソースバンドルを使用することによって、NumberFormatを使用できないことがわかります。 あなたはまだMessageFormat.format()にフォーマッタを呼び出すことができます。

NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance(Locale.US); 
currencyFormatter.setMaximumFractionDigits(0); 
System.err.println(MessageFormat.format("Some amount: {0}.", 
     currencyFormatter.format(1d))); 

は、予想通り、それが出て印刷します。

いくつかの量の:$ 1。

あなたが通貨を保持する必要がある場合は、私は地元のフォーマットを維持することにより、setCurrency(Currency)方法でプレイすることをお勧めしたい - あなたはとにかく内在タグでこの質問を求めています。


編集:MessageFormatの機能

に関する情報など、あなたがロケール用のカスタム通貨形式を使用する必要がある場合は、あなたが実際のMessageFormatクラス(通常の静的MessageFormat.format(String, Object...)は、Webアプリケーションでは動作しませんインスタンス化する必要がありますそれはあなたが好むなら、Javaロケールでデフォルトのロケール - Locale.getDefault(Locale.Category.FORMAT)を使用しているからです)。

(申し訳ありませんが、メモリ不足)このようになりますヘルパーメソッドを(申し訳ありませんが、ボーナス)書くことですので、あなたが本当にしたいこと:パフォーマンス上の理由から

public static String format(String pattern, Locale locale, Object... args) { 
    final String emptyPattern = ""; 
    final FieldPosition zero = new FieldPosition(0); 
    MessageFormat fmt = new MessageFormat(emptyPattern, locale); 
    StringBuffer buf = new StringBuffer(); // I just love it... 

    fmt.applyPattern(pattern); 
    fmt.format(args, buf, zero); 

    return buf.toString(); 
} 

、あなたは考えるかもしれません一度StringBufferを作成してからそれを一掃してください。しかし、私は自分自身に最適化を残しています。
また、パターンを少し変更する必要があるだろうと私は一瞬に説明しますなぜ:

String pattern = "{1}{0,number,\u00A4#}"; 

あなたがシンボルとどのようにを配置する金額と通貨記号と翻訳者に委ねを渡す必要がありますロケールのフォーマット値(プロパティファイルにコメントを追加することを忘れないでください!)

+0

あなたのクイックヘルプに感謝します。私は私の問題を十分に説明しなかった。私たちのシステムでは、正式なガイドラインに準拠している必要がある多くの文書を生成します。いくつかの金額はセントの一部として何も持たない必要があります(たとえば、ポーランドの場合、セントの部分に2桁の数字を追加することですが、それを減らす必要があります)が、他の状況では標準的な金銭の提示方法に固執します。したがって、システムワイドフォーマッタで小数点を設定するオプションはありません。そして、ResourceBundlesから取られた単一のメッセージのためにJavaで異なるフォーマッタを作成することは、お尻の痛みになります。 – Marti

+0

解決策が最初に機能しない理由を説明しましょう:[http://icu-project.org/apiref/icu4j/com/ibm/icu/util/CurrencyAmount.html] CurrencyAmountはNumberから派生しないため、プレーンなtoString )がフォーマット中に呼び出されます。それはあなたのために動作しません。今、私の編集を見てください:) –

関連する問題