自定义格式
原文: https://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html
您可以使用DecimalFormat
类将十进制数格式化为特定于语言环境的字符串。此类允许您控制前导和尾随零,前缀和后缀,分组(千)分隔符和小数分隔符的显示。如果要更改格式符号(例如小数点分隔符),可以将DecimalFormatSymbols
与DecimalFormat
类一起使用。这些类在数字格式化方面提供了极大的灵活性,但它们可以使您的代码更加复杂。
下面的文本使用演示DecimalFormat
和DecimalFormatSymbols
类的示例。此材料中的代码示例来自名为 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
是要格式化的数字,double
。 pattern
是指定格式属性的String
。 output
是String
,表示格式化的数字。
Output from DecimalFormatDemo
Program
| 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。 |
区域敏感格式
前面的示例为默认Locale
创建了DecimalFormat
对象。如果想要DecimalFormat
对象作为非默认Locale
,则实例化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
类。不寻常的格式是调用setDecimalSeparator
,setGroupingSeparator
和setGroupingSize
方法的结果。
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}integer{.fraction}{suffix}
prefix := '\\u0000'..'\\uFFFD' - specialCharacters
suffix := '\\u0000'..'\\uFFFD' - specialCharacters
integer := '#'* '0'* '0'
fraction := '0'* '#'*
上图中使用的符号如下表所示:
符号 | 描述 |
---|---|
X* |
0 个或更多个 X 实例 |
(X | Y) |
X 或 Y |
X..Y |
从 X 到 Y 的任何字符,包括在内 |
S - T |
S 中的字符,除了 T 中的字符 |
{X} |
X 是可选的 |
在前面的 BNF 图中,第一个子模式指定了正数的格式。第二个子模式是可选的,指定负数的格式。
虽然未在 BNF 图中注明,但逗号可能出现在整数部分内。
在子模式中,您可以使用特殊符号指定格式。这些符号如下表所述:
符号 | 描述 |
---|---|
0 | 一个数字 |
# | 一个数字,零显示为缺席 |
。 | 小数分隔符的占位符 |
, | 占位符用于分组分隔符 |
Ë | 为指数格式分隔尾数和指数 |
; | 分隔格式 |
- | 默认负前缀 |
% | 乘以 100 并显示为百分比 |
? | 乘以 1000 并按照 mille 显示 |
¤ | 货币符号;用货币符号代替;如果翻倍,用国际货币符号代替;如果存在于模式中,则使用货币小数分隔符而不是小数分隔符 |
X | 任何其他字符都可以在前缀或后缀中使用 |
“ | 用于引用前缀或后缀中的特殊字符 |