1

我有一个生成大量文档的系统。它的内容在 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。

4

1 回答 1

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 应用程序中不起作用,因为它使用默认区域设置 -Locale.getDefault(Locale.Category.FORMAT)在 Java 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#}";

您需要将金额和货币符号传递给翻译人员,将符号放置在哪里以及如何格式化区域设置的值(不要忘记在属性文件中添加注释!)。

于 2012-04-15T19:09:17.263 回答