如何在ICU4J中的MessageFormat中自定义货币格式

时间:2012-04-13 14:39:03

标签: java internationalization icu messageformat

我有一个生成大量文档的系统。其内容在ResourceBundles中定义。

我想自定义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。

有效

1 个答案:

答案 0 :(得分:1)

好的,我再次看了你的问题。 我真的不知道你为什么要砍掉美分部分(在美国,它在韩国或日本是有道理的,因为他们根本不使用它们。) 无论如何,我认为仅仅切断美分部分不是一个好主意,但如果你想这样做,就像使用setMaximumIntegerDigits(int)的NumberFormat一样简单。

顺便说一句,我仍然不知道我知道为什么使用资源包你不能使用NumberFormat。 您仍然可以在MessageFormat.format()中调用formatter:

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

可以预见它打印出来:

  

一些金额:1美元。

如果您需要保留货币,我建议您使用setCurrency(Currency)方法保留本地格式 - 无论如何,您在内化标签中都会问这个问题。


编辑:包含有关MessageFormat功能的信息

如果您需要为Locale使用自定义货币格式,您实际上需要实例化MessageFormat类(常规静态MessageFormat.format(String, Object...)在Web应用程序中不起作用,因为它使用Java中的默认语言环境 - Locale.getDefault(Locale.Category.FORMAT) 7 - 服务器区域设置,如果您愿意)。

所以你真正想要的是编写一个类似于此的帮助方法(抱歉,没有奖金)(内存不足,抱歉):

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#}";

您需要传递金额和货币符号,并留给转换器放置符号的位置以及如何格式化区域设置的值(不要忘记在属性文件中添加注释!)。