文档

Java™教程
隐藏目录
自定义格式
路径:国际化
课程:格式化
章节:数字和货币

自定义格式

您可以使用DecimalFormat类将十进制数格式化为与语言环境相关的字符串。该类允许您控制前导和尾随零、前缀和后缀、分组(千位)分隔符以及小数点分隔符的显示。如果您想要更改格式化符号,例如小数点分隔符,可以与DecimalFormat类一起使用DecimalFormatSymbols。这些类在数字格式化方面提供了很大的灵活性,但也可能使您的代码更复杂。

接下来的文本使用示例演示了DecimalFormatDecimalFormatSymbols类。本文中的代码示例来自名为DecimalFormatDemo的示例程序。

构建模式

您可以使用模式String指定DecimalFormat的格式化属性。模式决定了格式化后的数字的样式。有关模式语法的完整描述,请参阅数字格式模式语法

下面的示例通过将模式String传递给DecimalFormat的构造方法来创建一个格式化程序。 format方法接受一个double值作为参数,并返回一个String表示的格式化数字:

DecimalFormat myFormatter = new DecimalFormat(pattern);
String output = myFormatter.format(value);
System.out.println(value + " " + pattern + " " + output);

上述代码的输出描述在下表中。 value是要格式化的数字,一个doublepattern是指定格式化属性的Stringoutput是一个String,表示格式化后的数字。

DecimalFormatDemo程序的输出
value pattern output 解释
123456.789 ###,###.### 123,456.789 井号(#)表示一个数字,逗号是分组分隔符的占位符,点号是小数点的占位符。
123456.789 ###.## 123456.79 value小数点右侧有三位数字,但pattern只有两位。 format方法通过四舍五入处理此问题。
123.78 000000.000 000123.780 pattern指定前导和尾随零,因为使用0字符而不是井号(#)。
12345.67 $###,###.### $12,345.67 pattern中的第一个字符是美元符号($)。请注意,它紧跟在格式化的output中最左边的数字之前。
12345.67 \u00A5###,###.### ¥12,345.67 pattern指定了日元货币符号(¥),其Unicode值为00A5。

本地化敏感的格式化

前面的示例创建了一个默认LocaleDecimalFormat对象。如果你想要一个非默认LocaleDecimalFormat对象,你可以先实例化一个NumberFormat对象,然后将其强制转换为DecimalFormat。以下是一个示例:

NumberFormat nf = NumberFormat.getNumberInstance(loc);
DecimalFormat df = (DecimalFormat)nf;
df.applyPattern(pattern);
String output = df.format(value);
System.out.println(pattern + " " + output + " " + loc.toString());

运行上述代码示例会得到如下输出结果。格式化后的数字在第二列,根据Locale的不同而有所变化:

###,###.###      123,456.789     en_US
###,###.###      123.456,789     de_DE
###,###.###      123 456,789     fr_FR

到目前为止,这里讨论的格式化模式遵循美式英语的习惯。例如,在模式###,###.##中,逗号是千位分隔符,句点表示小数点。这种约定在没有向最终用户暴露的情况下是可以接受的。然而,某些应用程序(如电子表格和报表生成器)允许最终用户定义自己的格式化模式。对于这些应用程序,最终用户指定的格式化模式应该使用本地化的符号。在这些情况下,你需要在DecimalFormat对象上调用applyLocalizedPattern方法。

修改格式化符号

你可以使用DecimalFormatSymbols类来更改format方法生成的格式化数字中出现的符号。这些符号包括小数分隔符、分组分隔符、减号和百分号等。

下面的示例演示了如何使用DecimalFormatSymbols类对一个数字应用一个奇怪的格式。这个奇怪的格式是通过调用setDecimalSeparatorsetGroupingSeparatorsetGroupingSize方法得到的。

DecimalFormatSymbols unusualSymbols = new DecimalFormatSymbols(currentLocale);
unusualSymbols.setDecimalSeparator('|');
unusualSymbols.setGroupingSeparator('^');

String strange = "#,##0.###";
DecimalFormat weirdFormatter = new DecimalFormat(strange, unusualSymbols);
weirdFormatter.setGroupingSize(4);

String bizarre = weirdFormatter.format(12345.678);
System.out.println(bizarre);

运行此示例将以一种奇怪的格式打印数字:

1^2345|678

数字格式模式语法

你可以按照以下BNF图所指定的规则,设计自己的数字格式模式:

pattern    := subpattern{;subpattern}
subpattern := {prefix}整数{.小数}{suffix}
prefix     := '\\u0000'..'\\uFFFD' - 特殊字符
suffix     := '\\u0000'..'\\uFFFD' - 特殊字符
整数        := '#'* '0'* '0'
小数        := '0'* '#'*

上述图表中使用的符号解释如下表所示:

符号 解释
X* X的0个或多个实例
(X | Y) X或Y
X..Y 从X到Y之间的任意字符,包括X和Y
S - T S中的字符,但不包括T中的字符
{X} X是可选的

在上述BNF图表中,第一个子模式指定了正数的格式。第二个子模式是可选的,指定了负数的格式。

尽管BNF图表中没有提到,但整数部分中可能出现逗号。

在子模式中,您可以使用特殊符号来指定格式。这些符号在下表中描述:

符号 解释
0 一个数字
# 一个数字,如果为零则不显示
. 小数点的占位符
, 分组分隔符的占位符
E 指数格式中的尾数和指数分隔符
; 分隔不同的格式
- 默认的负数前缀
% 乘以100,并显示为百分比
? 乘以1000,并显示为千分比
¤ 货币符号;替换为货币符号;如果重复两次,则替换为国际货币符号;如果在模式中出现,则使用货币小数分隔符代替小数分隔符
X 前缀或后缀中可以使用任何其他字符
' 用于引用前缀或后缀中的特殊字符

上一页: 使用预定义格式
下一页: 日期和时间