如果我們用下列語句輸出一個數
System.out.println(123456.789);
将會在Console看到輸出
123456.789
那麼如何得到123,456.789這種格式化的輸出呢?這裡就需要用到java.text.Format這個類。不僅是數字,它還提供了貨币值和百分數的格式化輸出,比如0.58的百分數輸出形式是58%。要獲得本地的預設格式,可以用下列方法獲得
NumberFormat.getNumberInstance()
NumberFormat.getCurrencyInstance()
NumberFormat.getOPercentInstance()
而要獲得某個國家或地區的具體格式,可以使用參數Local.XXX,如Locale.GERMANY,Locale.UK。
NumberFormat formatter = NumberFormat.getNumberInstance(Locale.GERMANY);
範例
import java.text.NumberFormat;
import java.util.Locale;
public class FormatTest {
public static void main(String args[]) {
// 不使用格式化輸出數
double d = 10000.0 / 3.0;
System.out.println("無格式化輸出:" + d);
// 使用本地預設格式輸出數
NumberFormat numberFormat = NumberFormat.getNumberInstance();
//numberFormat.setMaximumFractionDigits(4);
//numberFormat.setMinimumIntegerDigits(6);
String numberString = numberFormat.format(d);
System.out.println("本地預設格式輸出數:" + numberString);
// 使用本地預設格式輸出貨币值
NumberFormat currencyFormat = NumberFormat.getCurrencyInstance();
System.out.println("本地預設格式輸出貨币值:" + currencyFormat.format(d));
// 使用本地預設格式輸出百分數
NumberFormat percentFormat = NumberFormat.getPercentInstance();
System.out.println("本地預設格式輸出百分數:" + percentFormat.format(d));
// 在不同的國家和地區數字表示的格式也有差別。如德國
// 使用德國的格式化輸出數
NumberFormat numberFormatG = NumberFormat
.getNumberInstance(Locale.GERMANY);
System.out.println("德國數字輸出形式:" + numberFormatG.format(d));
// 使用德國貨币輸出形式
NumberFormat currencyFormatG = NumberFormat
.getCurrencyInstance(Locale.GERMANY);
System.out.println("德國貨币輸出形式:" + currencyFormatG.format(d));
// 使用美國貨币輸出形式
NumberFormat currencyFormatA = NumberFormat
.getCurrencyInstance(Locale.US);
System.out.println("美國貨币輸出形式:" + currencyFormatA.format(d));
// 使用德國百分數輸出形式
NumberFormat percentFormatG = NumberFormat
.getPercentInstance(Locale.GERMANY);
System.out.println("德國百分數輸出形式:" + percentFormatG.format(d));
System.exit(0);
}
}
程式輸出
<!--[if !vml]--><!--[endif]-->
由于歐元符号無法在此Console輸出,是以顯示?
可以指定顯示的最多(或最少)整數位和小數位。如
double d = 10000.0 / 3.0;
NumberFormat numberFormat = NumberFormat.getNumberInstance();
numberFormat.setMaximumFractionDigits(4);
numberFormat.setMinimumIntegerDigits(6);
String numberString = numberFormat.format(d);
System.out.println(numberString);
輸出:
003,333.3333。整數位不夠的補零,小數截去部分四舍五入。
也可以利用NumberFormat的一個子類DecimalFormat來指定輸出格式。
DecimalFormat decimalFormat = new DecimalFormat("######.0000");
String s = decimalFormat.format(d);
和前面一樣,顯示六個整數位和4個小數位。
下面對格式化的數字進行解析。
import java.util.Locale;
import java.text.NumberFormat;
import java.text.ParseException;
public class ParseFormat {
public static void main(String args[]) {
// 本地格式的解析
NumberFormat numberFormat1 = NumberFormat.getNumberInstance();
Number numb1 = null;
try {
numb1 = numberFormat1.parse("33,333.33");
} catch (ParseException e1) {
System.err.println(e1);
}
System.out.println(numb1);
// 以德國格式解析
NumberFormat numberFormat2 = NumberFormat
.getNumberInstance(Locale.GERMAN);
Number numb2 = null;
try {
numb2 = numberFormat2.parse("33,333.33");
} catch (ParseException e2) {
System.err.println(e2);
}
System.out.println(numb2);
System.exit(0);
}
}
程式輸出:
33333.33
33.333
同樣一種格式33,333.33,有人将之了解為33333.33,也有人認為它是33.333,軟體國際化的重要性可見一斑。
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=931879
16:47
浏覽 (1563)
評論 (1)
分類: 技術文章
相關推薦
評論
locoray 2007-11-30 回複
java的資料格式化
java.text 包允許通過與特定語言無關的方式格式化文本消息、日期和數值。
1.資料格式化相關類介紹
類功能介紹
java.util.*
Locale 表示一個語言和區域的特定組合
ResourceBundle ListResourceBundle
PropertyResourceBundle 擷取本地化資源中(可以表現為類和資源檔案)的資訊
Calendar GregorianCalendar 月曆的支援
TimeZone SimpleTimeZone 時區的支援
Currency 單獨處理和貨币相關的操作
java.text.*
Format NumberFormat
DecimalFormat 格式化 格式化數字、貨币以及百分數
ChoiceFormat 處理複數形式
DateFormat SimpleDateFormat 日期和時間的格式化
MessageFormat 消息的格式化
DecimalFormatSymbols、DateFormatSymbols 自定義格式化中的符号集
FieldPosition 被Format及其子類用來在格式化輸出中辨別字段
Collator RuleBasedCollator 字元串操作 比較字元串
CollationElementIterator 獲得一個字元串中單個字元的枚舉資訊
CollationKey 優化比較性能
BreakIterator 獲得文本中的個體資訊,比如字元、單詞、句子以及整行等資訊
java.lang.*
Character 檢查字元屬性
2.國際化及MessageFormat類
MessageFormat 運作開發者輸出文本中的變量的格式,它主要用于國際化。它是一個強大的類,就像下面的例子展示的那樣:
String message =
"Once upon a time ({1,date}, " +
"around about {1,time,short}), there " +
"was a humble developer named Geppetto" +
" who slaved for "{0,number,integer}" +
"days with {2,number,percent} complete " +
"user requirements. ";
Object[ ] variables =
new Object[ ] { new Integer(4),
new Date( ),
new Double(0.21)
}
String output = MessageFormat.format( message, variables );
System.out.println(output);
隐藏在資訊中的是描述輸出的格式的一種短小的代碼,範例的輸出如下:
Once upon a time (Nov 3, 2002, around about 1:35 AM), there was a humble developer named Geppetto who slaved for 4 days with 21% complete user requirements.
如果相同的資訊需要被重複輸出但是變量的值不同,那麼建立一個MessageFormat 對象并給出資訊。下面是上面的例子的修正版:
// String output = MessageFormat.format( message, variables );
// 變為:
MessageFormat formatter = new MessageFormat(message);
String output = formatter.format(variables);
除了可以處理日期、時間、數字和百分數外,MessageFormat 也可以處理貨币,運作更多的數字格式的控制并且允許指定ChoiceFormat。 MessageFormat 是一個極好的類,它應該經常被使用但是現在還沒有。它的最大的缺點是資料是被作為變量傳遞而不是一個Properties對象。一個簡單的解決辦法是寫一 個封裝類,它會預解析字元串為格式化的結果,将Properties的key轉換為一個數組索引,順序是Properties.keys( )傳回的順序。
3.數值格式化
3.1.有關numberformat
如果您來自美國,您會在較大的數值中間放置逗号來表示千和百萬(等等,每三個數值使用一個逗号)。對于浮點數,您将在整數部分和小數部分之間放置小 數點。對于金錢,貨币符号 $ 放在金額的前面。如果 您從來沒有到過美國以外的地方,可能就不會關心用英鎊(£)來格式化的英國貨币,或者用歐元(?)來表示的其他歐洲國家的貨币。
對于那些我們确實關心的貨币,我們可以使用 NumberFormat 及其相關的類來格式化它們。開發人員使用 NumberFormat 類來讀取使用者輸入的數值,并格式化将要顯示給使用者看的輸出。
在Java的I/O裡,并沒有所謂的型别,不管是int、long、double…最後都是以String輸出,是以如果要讓數字以特定格式輸出, 需透過Java提供的兩個類别java.text.NumberFormat和java.text.DecimalFormat将數字格式化後再輸出。
在開始使用NumberFormat時,應先用getInstance取得NumberFormat的實體,範例12中的 setMaximumIntegerDigits和setMinimumFractionDigits是用來設定整數和小數的位數,另外還有 setMinimumIntegerDigits和setMaximumFractionDigits也是同樣功能。這些設定如有沖突,Java以最後設 定的為準。
import java.text.*;
public class myFormat {
public myFormat() {
NumberFormat nf = NumberFormat.getInstance();
double dblNum = Math.PI;
System.out.println(dblNum);
nf.setMaximumIntegerDigits(5);
nf.setMinimumFractionDigits(4);
System.out.println("PI: " + nf.format(dblNum));
}
public static void main(String[] args) {
myFormat myFormat1 = new myFormat();
}
}
與 DateFormat 類似,NumberFormat 是一個抽象類。您永遠不會建立它的執行個體??相反, 您總是使用它的子類。雖然可以通過子類的構造函數直接建立子類,不過NumberFormat 類提供了一系列 getXXXInstance() 方法,用以獲得不同類型的數值類的特定地區版本。這樣的方法共有五個:
getCurrencyInstance()
getInstance()
getIntegerInstance()
getNumberInstance()
getPercentInstance()
具體使用哪一個方法取決于您想要顯示的數值類型(或者想要接受的輸入類型)。每個方法都提供了兩個版本??一個版本适用于目前地區,另一個版本接受一個 Locale作為參數,以便可能地指定一個不同的地區。
使用 NumberFormat 的基本過程是獲得一個執行個體并使用該執行個體。挑選恰當的執行個體的确需要費一番思量。通常 您不希望使用通用的 getInstance 或者 getNumberInstance() 版本,因為 您不确切知道您将會得到什麼。相反,您會使用像 getIntegerInstance() 這樣的方法,因為 您希望把某些内容顯示為整數而不需要任何小數值。清單1展示了這一點,我們在其中把數值 54321 顯示為适合于美國和德國的格式。
清單 1. 使用 NumberFormat
import java.text.*;
import java.util.*;
public class IntegerSample {
public static void main(String args[]) {
int amount = 54321;
NumberFormat usFormat =
NumberFormat.getIntegerInstance(Locale.US);
System.out.println(usFormat.format(amount));
NumberFormat germanFormat =
NumberFormat.getIntegerInstance(Locale.GERMANY);
System.out.println(germanFormat.format(amount));
}
}
運作該代碼将産生如清單2所示的輸出。注意第一種格式(美國)中的逗号分隔符和第二種格式中的點号分隔符。清單 2. NumberFormat 輸出
54,321
54.321
雖然 NumberFormat 是一個抽象類,并且您将通過像 getIntegerInstance() 這樣的各種方法來使用它的執行個體,但是 DecimalFormat 類提供了該類的一個具體版本。 您可以顯式地指定字元模式,用以确定如何顯示正數、負數、小數和指數。如果不喜歡用于不同地區的預定義格式,您可以建立自己的格式。(在内部,或許 NumberFormat 使用的就是 DecimalFormat。)。
3.2.使用 Currency 進行貨币計算
前面提到過的 getCurrency() 和setCurrency() 方法傳回新的 java.util.Currency 類的一個執行個體。這個類允許通路不同國家的 ISO 4217 貨币代碼。雖然自從 getCurrencyInstance() 引入以來您就能配合 NumberFormat 一起使用它,然而除了它們的數字顯示外, 您永遠不能獲得或顯示某個地區的貨币符号。有了Currency 類,現在很容易就可以做到這一點。
正如前面提到過的,貨币代碼來自ISO 4217。通過傳入某個國家的 Locale 或者貨币的實際字母代碼,Currency.getInstance() 将傳回一個有效的 Currency 對象。NumberFormat 的 getCurrency() 方法将在建立特定地區的貨币執行個體之後做同樣的事情。 清單7顯示了如何獲得貨币執行個體,以及如何格式化将要顯示為貨币的數值。記住這些轉換僅用于顯示。如果需要在貨币之間轉換金額,應該在确定如何顯示值之前進 行轉換。
清單 7. 使用 getCurrencyInstance() 和 Currency
import java.text.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;
public class CurrencySample {
public static void main(String args[]) {
StringBuffer buffer = new StringBuffer(100);
Currency dollars = Currency.getInstance("USD");
Currency pounds = Currency.getInstance(Locale.UK);
buffer.append("Dollars: ");
buffer.append(dollars.getSymbol());
buffer.append("\n");
buffer.append("Pound Sterling: ");
buffer.append(pounds.getSymbol());
buffer.append("\n-----\n");
double amount = 5000.25;
NumberFormat usFormat = NumberFormat.getCurrencyInstance(Locale.US);
buffer.append("Symbol: ");
buffer.append(usFormat.getCurrency().getSymbol());
buffer.append("\n");
buffer.append(usFormat.format(amount));
buffer.append("\n");
NumberFormat germanFormat =
NumberFormat.getCurrencyInstance(Locale.GERMANY);
buffer.append("Symbol: ");
buffer.append(germanFormat.getCurrency().getSymbol());
buffer.append("\n");
buffer.append(germanFormat.format(amount));
JFrame frame = new JFrame("Currency");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTextArea ta = new JTextArea(buffer.toString());
JScrollPane pane = new JScrollPane(ta);
frame.getContentPane().add(pane, BorderLayout.CENTER);
frame.setSize(200, 200);
frame.show();
}
}
遺憾的是,為歐元或者英鎊傳回的貨币符号不是實際的符号,而是三位的貨币代碼(來自 ISO 4217)。然而在使用 getCurrencyInstance() 的情況下,實際的符号将會顯示出來.
3.3.DecimalFormat
NumberFormat.getInstance()方法傳回NumberFormat的一個執行個體(實際上是NumberFormat具體的一個 子類,例如DecimalFormat), 這适合根據本地設定格式化一個數字。你也可以使用非預設的地區設定,例如德國。然後格式化方法根據特定的地區規則格式化數字。這個程式也可以使用一個簡單 的形式:
NumberFormat.getInstance().format(1234.56)
但是儲存一個格式然後重用更加有效。國際化是格式化數字時的一個大問題。
另一個是對格式的有效控制,例如指定小數部分的位數,下面是解決這個問題的一個簡單例子:
import java.text.DecimalFormat;
import java.util.Locale;
public class DecimalFormat2 {
public static void main(String args[]) {
// 得到本地的預設格式
DecimalFormat df1 = new DecimalFormat("####.000");
System.out.println(df1.format(1234.56));
// 得到德國的格式
Locale.setDefault(Locale.GERMAN);
DecimalFormat df2 = new DecimalFormat("####.000");
System.out.println(df2.format(1234.56));
}
}
在這個例子中設定了數字的格式,使用像"####.000"的符号。這個模式意味着在小數點前有四個數字,如果不夠就空着,小數點後有三位數字,不足用0補齊。程式的輸出:
1234.560
1234,560
相似的,也可以控制指數形式的格式,例如:
import java.text.DecimalFormat;
public class DecimalFormat3 {
public static void main(String args[]) {
DecimalFormat df = new DecimalFormat("0.000E0000");
System.out.println(df.format(1234.56));
}
}
輸出:
1.235E0003
對于百分數:
import java.text.NumberFormat;
public class DecimalFormat4 {
public static void main(String args[]) {
NumberFormat nf = NumberFormat.getPercentInstance();
System.out.println(nf.format(0.47));
}
}
輸出:
47%
至此,你已經看到了格式化數字的幾個不同的技術。另一方面,如何讀取并解析包含格式化的數字的字元串?解析支援包含在NumberFormat中。例如:
import java.util.Locale;
import java.text.NumberFormat;
import java.text.ParseException;
public class DecimalFormat5 {
public static void main(String args[]) {
// 本地格式
NumberFormat nf1 = NumberFormat.getInstance();
Object obj1 = null;
// 基于格式的解析
try {
obj1 = nf1.parse("1234,56");
}
catch (ParseException e1) {
System.err.println(e1);
}
System.out.println(obj1);
// 德國格式
NumberFormat nf2 =NumberFormat.getInstance(Locale.GERMAN);
Object obj2 = null;
// 基于格式的解析
try {
obj2 = nf2.parse("1234,56");
}
catch (ParseException e2) {
System.err.println(e2);
}
System.out.println(obj2);
}
}
這個例子分兩部分,都是解析一個字元串:"1234,56"。第一部分使用本地格式解析,第二部分使用德國格式解析。當程式在美國運作,結果是:
123456
1234.56
換句話說,"1234,56"在美國被認為是一個巨大的整數"123456"而在德國被認為是一個小數"1234.56"。
3.4.DecimalFormat 和 NumberFormat的聯系
在上面的例子中, DecimalFormat 和 NumberFormat 都被使用了。DecimalFormat 常用于獲得很好的格式控制,而NumberFormat 常用于指定不同于本地的地區。如何結合兩個類呢?
答案圍繞着這樣的事實:DecimalFormat是NumberFormat的一個子類,其執行個體被指定為特定的地區。是以,你可以使用 NumberFormat.getInstance 指定一個地區,然後将結構強制轉換為一個DecimalFormat對象。文檔中提到這個技術可以在大多情況下适用,但是你需要用try/catch 塊包圍強制轉換以防轉換不能正常工作 (大概在非常不明顯得情況下使用一個奇異的地區)。下面是一個這樣的例子:
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
public class DecimalFormat6 {
public static void main(String args[]) {
DecimalFormat df = null;
// 得到一個NumberFormat 對象并
// 強制轉換為一個 DecimalFormat 對象
try {
df = (DecimalFormat)NumberFormat.getInstance(Locale.GERMAN);
}
catch (ClassCastException e) {
System.err.println(e);
}
// 設定格式模式
df.applyPattern("####.00000");
// format a number
System.out.println(df.format(1234.56));
}
}
getInstance() 方法獲得格式,然後調用applyPattern()方法設定格式模式,輸出:
1234,56000
如果你不關心國際化,可以直接使用DecimalFormat 。
其中v 為未處理的double,scale為需求精度,傳回需要小數位數的double
public static double round(double v,int scale){
if(scale<0){
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(Double.toString(v));
BigDecimal one = new BigDecimal("1");
return b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
}
package com.minght.sys.util;
import java.text.*;
import java.util.*;
import java.math.*;
public class ObjectFormat {
public ObjectFormat() {
}
public static String formatNumber(double d,String pattern,Locale l){
String s = "";
try{
DecimalFormat nf = (DecimalFormat) NumberFormat.getInstance(l);
nf.applyPattern(pattern);
s = nf.format(d);
}catch(Exception e){
e.printStackTrace();
Debug.println(" formatNumber is error!");
}
return s;
}
public static String formatNumber(double d,String pattern){
return formatNumber(d,pattern,Locale.getDefault());
}
public static String formatCurrency(double d,String pattern,Locale l){
String s = "";
try{
DecimalFormat nf = (DecimalFormat) NumberFormat.getCurrencyInstance(l);
nf.applyPattern(pattern);
s = nf.format(d);
}catch(Exception e){
e.printStackTrace();
Debug.println(" formatNumber is error!");
}
return s;
}
public static String formatCurrency(double d,String pattern){
return formatCurrency(d,pattern,Locale.getDefault());
}
public static String formatCurrency(double d){
String s = "";
try{
DecimalFormat nf = (DecimalFormat) NumberFormat.getCurrencyInstance();
s = nf.format(d);
}catch(Exception e){
e.printStackTrace();
Debug.println(" formatNumber is error!");
}
return s;
}
public static String formatPercent(double d,String pattern,Locale l){
String s = "";
try{
DecimalFormat df = (DecimalFormat)NumberFormat.getPercentInstance(l);
df.applyPattern(pattern);
s = df.format(d);
}catch(Exception e){
Debug.print(e,"formatPercent is error!");
}
return s;
}
public static String formatPercent(double d,String pattern){
return formatPercent(d,pattern,Locale.getDefault());
}
public static String formatPercent(double d){
String s = "";
try{
DecimalFormat df = (DecimalFormat)NumberFormat.getPercentInstance();
s = df.format(d);
}catch(Exception e){
Debug.print(e,"formatPercent is error!");
}
return s;
}
public static String numberFormat(BigDecimal bd, String format) {
if (bd == null || "0".equals(bd.toString())) {
return "";
}
DecimalFormat bf = new DecimalFormat(format);
return bf.format(bd);
}
public static void main(String[] args) {
String s = formatCurrency(11123.89343,"$##,##.000");
System.out.println(s);
}
}