眀海棠文集之数据格式化1.0

眀海棠文集之数据格式化1.0

 

java.text 包允许通过与特定语言无关的方式格式化文本消息、日期和数值。

1.       数据格式化相关类介绍

功能介绍

java.util.*

Locale

表示一个语言和区域的特定组合

ResourceBundle

ListResourceBundle

PropertyResourceBundle

获取本地化资源中(可以表现为类和资源文件)的信息

Calendar

GregorianCalendar

日历的支持

TimeZone

SimpleTimeZone

时区的支持

Currency

单独处理和货币相关的操作

java.text.*

Format

NumberFormat

 

DecimalFormat

格式化

格式化数字、货币以及百分数

ChoiceFormat

处理复数形式

DateFormat

SimpleDateFormat

日期和时间的格式化

MessageFormat

 

消息的格式化

DecimalFormatSymbolsDateFormatSymbols

自定义格式化中的符号集

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对象。一个简单的解决办法是写一个封装类,它会预解析字符串为格式化的结果,将Propertieskey转换为一个数组索引,顺序是Properties.keys( )返回的顺序。

3.      数值格式化

3.1. 有关numberformat

如果您来自美国,您会在较大的数值中间放置逗号来表示千和百万(等等,每三个数值使用一个逗号)。对于浮点数,您将在整数部分和小数部分之间放置小数点。对于金钱,货币符号 $ 放在金额的前面。如果 您从来没有到过美国以外的地方,可能就不会关心用英镑(£)来格式化的英国货币,或者用欧元()来表示的其他欧洲国家的货币。

对于那些我们确实关心的货币,我们可以使用 NumberFormat 及其相关的类来格式化它们。开发人员使用 NumberFormat 类来读取用户输入的数值,并格式化将要显示给用户看的输出。

JavaI/O里,并没有所谓的型别,不管是intlongdouble…最後都是以String输出,所以如果要让数字以特定格式输出,需透过Java提供的两个类别java.text.NumberFormatjava.text.DecimalFormat将数字格式化後再输出。

在开始使用NumberFormat时,应先用getInstance取得NumberFormat的实体,范例12中的setMaximumIntegerDigitssetMinimumFractionDigits是用来设定整数和小数的位数,另外还有setMinimumIntegerDigitssetMaximumFractionDigits也是同样功能。这些设定如有冲突,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 常用于指定不同于本地的地区。如何结合两个类呢?

答案围绕着这样的事实:DecimalFormatNumberFormat的一个子类,其实例被指定为特定的地区。因此,你可以使用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.*;

/**
 * <p>Title: 格式化:开源,开放</p>
 * <p>Description: opeansource</p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: 眀海棠</p>
 * @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);
  }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值