格式化數值和貨幣 (jsp格式化數字和貨幣)

來源:互聯網
上載者:User

【轉載】http://www-128.ibm.com/developerworks/cn/java/j-mer08133/

java.text 包允許通過與特定語言無關的方式格式化簡訊、日期和數值。許多人配合 MessageFormat 類使用資源套件來為使用者本地化訊息。更多的人似乎使用 DateFormat SimpleDateFormat 類來操作日期文字,既用於輸入也用於輸出。最少見的用法似乎是使用 NumberFormat 類及其相關的子類 DecimalFormat ChoiceFormat 。在本月的討論中,我們將研究一下這三個未得到充分利用的類以及 Currency 類,看看 J2SE 1.4 已經變得有多麼的全球化。

數值格式化基類:NumberFormat
如果您來自美國,您會在較大的數值中間放置逗號來表示千和百萬(等等,每三個數值使用一個逗號)。對於浮點數,您將在整數部分和小數部分之間放置小數點。對於金錢,貨幣符號 $ 放在金額的前面。如果 您從來沒有到過美國以外的地方,可能就不會關心用元(¥)來格式化的日本貨幣,用英鎊(£)來格式化的英國貨幣,或者用歐元(€)來表示的其他歐洲國家的貨幣。

對於那些我們確實關心的貨幣,我們可以使用 NumberFormat 及其相關的類來格式化它們。開發人員使用 NumberFormat 類來讀取使用者輸入的數值,並格式化將要顯示給使用者看的輸出。

DateFormat 類似, NumberFormat 是一個抽象類別。您永遠不會建立它的執行個體――相反,您總是使用它的子類。雖然可以通過子類的建構函式直接建立子類,不過 NumberFormat 類提供了一系列 get XXXInstance() 方法,用以獲得不同類型的數值類的特定地區版本。這樣的方法共有五個:

  • getCurrencyInstance()
  • getInstance()
  • getIntegerInstance()
  • getNumberInstance()
  • getPercentInstance()

具體使用哪一個方法取決於您想要顯示的數實值型別(或者想要接受的輸入類型)。每個方法都提供了兩個版本――一個版本適用於當前地區,另一個版本接受一個 Locale作為參數,以便可能地指定一個不同的地區。

在 J2SE 1.4中, NumberFormat 新增的內容是 getIntegerInstance()、 getCurrency() setCurrency() 方法。下面讓我們研究一下新的 getIntegerInstance() 方法。稍後將會探討 get/set 貨幣方法。

使用 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,32154.321

學習如何迭代 DecimalFormat 中的字元
雖然 NumberFormat 是一個抽象類別,並且您將通過像 getIntegerInstance() 這樣的各種方法來使用它的執行個體,但是 DecimalFormat 類提供了該類的一個具體版本。 您可以顯式地指定字元模式,用以確定如何顯示正數、負數、小數和指數。如果不喜歡用於不同地區的預定義格式,您可以建立自己的格式。(在內部,或許 NumberFormat 使用的就是 DecimalFormat 。)基本的 DecimalFormat 功能在 J2SE 平台的 1.4 版中並沒有改變。改變之處在於添加了 formatToCharacterIterator()、 getCurrency() setCurrency() 方法。

我們將快速探索一下新的 formatToCharacterIterator 方法及其關聯的 NumberFormat.Field 類。J2SE 1.4 引入了 CharacterIterator 的概念,它允許雙向地遍曆文本。對於 formatToCharacterIterator ,您將獲得它的子介面 AttributedCharacterIterator ,這個子介面允許您找出關於該文本的資訊。對於 DecimalFormat 的情況 那些屬性是來自 NumberFormat.Field 的鍵 通過使用 AttributedCharacterIterator , 您完全可以根據所產生的結果構造自己的字串輸出 清單3使用了一個百分數執行個體來提供一個簡單的示範:

清單 3. 使用 formatToCharacterIterator()

import java.text.*;import java.util.*;public class DecimalSample {  public static void main(String args[]) {    double amount = 50.25;    NumberFormat usFormat = NumberFormat.getPercentInstance(Locale.US);    if (usFormat instanceof DecimalFormat) {      DecimalFormat decFormat = (DecimalFormat)usFormat;      AttributedCharacterIterator iter =        decFormat.formatToCharacterIterator(new Double(amount));        for (char c = iter.first();            c != CharacterIterator.DONE;            c = iter.next()) {          // Get map for current character          Map map = iter.getAttributes();          // Display its attributes          System.out.println("Char: " + c + " / " + map);     }    }  }}

清單4顯示了程式的輸出(顯示在一小段訊息之後,以使其更易於閱讀)。基本上, formatToCharacterIterator() 方法的工作方式與調用 format() 相同,只不過前者除了格式化輸出字串外,還要使用屬性來標記輸出中的每個字元(例如,位於位置 X 處的字元是否為一個整數?)。將 50.25 顯示為百分數,在美國地區的輸出為“5,025%”。通過檢查輸出 除“%”外的每個字元都是整數,包括冒號 除了數值之外 逗號也被標記為一個分組分隔字元,百分比符號被標記為一個百分數。每個數位屬性都是一個 java.util.Map ,其中每個屬性被顯示為 key=value (鍵=值)的形式。在存在多個屬性的情況下,屬性列表中的屬性之間用逗號分隔。

清單 4. formatToCharacterIterator() 輸出

Char: 5 / {java.text.NumberFormat$Field(integer)=  java.text.NumberFormat$Field(integer)}Char: , / {java.text.NumberFormat$Field(grouping separator)=  java.text.NumberFormat$Field(grouping separator),  java.text.NumberFormat$Field(integer)=  java.text.NumberFormat$Field(integer)}Char: 0 / {java.text.NumberFormat$Field(integer)=  java.text.NumberFormat$Field(integer)}Char: 2 / {java.text.NumberFormat$Field(integer)=  java.text.NumberFormat$Field(integer)}Char: 5 / {java.text.NumberFormat$Field(integer)=  java.text.NumberFormat$Field(integer)}Char: % / {java.text.NumberFormat$Field(percent)=  java.text.NumberFormat$Field(percent)}

基於值範圍和 ChoiceFormat 確定訊息
ChoiceFormat NumberFormat 的另一個具體子類。它的定義和行為在 J2SE 1.4 中沒有改變。 ChoiceFormat 並不會真正協助您格式化數值,但它的確允許您自訂與某個值關聯的文本。在最簡單的情況下,我們可以設想一下顯示出錯訊息的情況。如果存在導致失敗的單個原因,您希望使用單詞“is”。如果有兩個或者多個原因,您希望使用單詞“are”。如清單5所示, ChoiceFormat 允許您把一系列的值對應為不同的文本字串。

ChoiceFormat 類通常與 MessageFormat 類一起使用,以產生與語言無關的拼接起來的訊息。這裡沒有說明的是如何使用 ResourceBundle (它通常與 ChoiceFormat 一起使用)來獲得那些字串。關於如何使用資源套件的資訊 請參見 參考資料;特別地,“Java 國際化基礎”教程提供了關於這方面的深入討論

清單 5. 使用 ChoiceFormat

import java.text.*;import java.util.*;public class ChoiceSample {  public static void main(String args[]) {    double limits[] = {0, 1, 2};    String messages[] = {      "is no content",      "is one item",      "are many items"};    ChoiceFormat formats = new ChoiceFormat(limits, messages);    MessageFormat message = new MessageFormat("There {0}.");    message.setFormats(new Format[]{formats});    for (int i=0; i<5; i++) {      Object formatArgs[] = {new Integer(i)};      System.out.println(i + ": " + message.format(formatArgs));    }  }}   

執行該程式將產生如清單6所示的輸出:

清單 6. ChoiceFormat 輸出

0: There is no content.1: There is one item.2: There are many items.3: There are many items.4: There are many items.

使用 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() 的情況下,實際的符號將會顯示出來,1所示。

圖 1. 看見實際的貨幣符號

結束語
對於軟體全球化來說,所需做的不僅僅是自訂簡訊。雖然把簡訊轉移到資源套件中至少完成了工作的一半,但是也不要忘了處理與地區密切相關的數值和貨幣顯示。並不是每個人都像在美國一樣使用冒號和點號來進行數字顯示,每個人都必須處理自己的貨幣細節。雖然我們不必依賴像 $$$.99 這樣的老式 COBOL 圖形字串,但是通過使用特定於地區的 NumberFormat 執行個體, 您可以使自己的程式更加國際化。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.