Java數字、貨幣值和百分數等的格式化處理

comeontony發表於2011-12-07

如果我們用下列語句輸出一個數

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.*;

/**

* Title: 格式化:開源,開放

* Description: opeansource

* Copyright: Copyright (c) 2004

* Company: ?海棠

* @author HaiTang Ming

* @version 1.0

*/

public class ObjectFormat {

public ObjectFormat() {

}

/**

   * 將給定的數字按給定的形式輸出

   * @param d double

   * @param pattern String

   *       #:表示有數字則輸出數字,沒有則空,如果輸出位數多於#的位數,

   *          則超長輸入

   *       0:有數字則輸出數字,沒有補0

   *          對於小數,有幾個#或0,就保留幾位的小數;

   *       例如: "###.00" -->表示輸出的數值保留兩位小數,不足兩位的

   *                          補0,多於兩位的四捨五入

   *              "###.0#" -->表示輸出的數值可以保留一位或兩位小數;

   *                               整數顯示為有一位小數,一位或兩位小數

   *                               的按原樣顯示,多於兩位的四捨五入;

   *              "###" --->表示為整數,小數部分四捨五入

   *              ".###" -->12.234顯示為.234

   *              "#,###.0#" -->表示整數每隔3位加一個",";

   * @param l Locale

   * @return String

   */

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;

}

/**

   * 按預設的區域輸出數字形式

   * @param d double

   * @param pattern String

   * @return String

   */

public static String formatNumber(double d,String pattern){

    return formatNumber(d,pattern,Locale.getDefault());

}

/**

   * 格式化貨幣

   * @param d double

   * @param pattern String

   *        "\u00A4#,###.00" :顯示為 ¥1,234,234.10

   * @param l Locale

   * @return String

   */

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;

}

/**

   * 使用預設區域的指定方式顯示貨幣

   * @param d double

   * @param pattern String

   * @return String

   */

public static String formatCurrency(double d,String pattern){

    return formatCurrency(d,pattern,Locale.getDefault());

}

/**

   * 使用預設方式顯示貨幣:

   *     例如:¥12,345.46 預設保留2位小數,四捨五入

   * @param d double

   * @return String

   */

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;

}

/**

   * 按指定區域格式化百分數

   * @param d

   * @param pattern :"##,##.000%"-->不要忘記“%”

   * @param l

   * @return

   */

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;

}

/**

   * 使用預設區域格式化百分數

   * @param d

   * @param pattern

   * @return

   */

public static String formatPercent(double d,String pattern){

   return formatPercent(d,pattern,Locale.getDefault());

}

/**

* 格式化百分數

* @param d

* @return

*/

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;

}

/**

   * 輸出數字的格式,如:1,234,567.89

   * @param bd BigDecimal 要格式華的數字

   * @param format String 格式 "###,##0"

   * @return String

   */

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);

}

}

相關文章