本文参考:

有时会想把数字,日期,字符串按照给定规则给格式化。SUN JDK为我们提供了这个API,它是java.util.Formatter。此类提供了对布局对齐和排列的支持,以及

对数值、字符串和日期/时间数据的常规格式和特定于语言环境的输出的支持。

如何格式化?

给定规则:

要想按照自己的想法格式化必须事先编写一个规则。那这个规则要怎么编写?

1.常规类型、字符类型和数值类型的格式说明符的语法如下:

%[argument_index$][flags][width][.precision]conversion

2.用来表示日期和时间类型的格式说明符的语法如下:

%[argument_index$][flags][width]conversion

3.与参数不对应的格式说明符的语法如下:

%[flags][width]conversion

API中有这样三种规则,很显然第一个规则的内容是最全面的。其它规则的内容和第一规则的内容有重复,那单说第一规则内容,其它规则依次类推。

注意:规则一中的precision前面要加英文句号“.”

API有以下解释:

可选的
argument_index
是一个十进制整数,用于表明参数在参数列表中的位置。第一个参数由 "1$"引用,第二个参数由"2$"引用,依此类推。

可选
flags
是修改输出格式的字符集。有效标志集取决于转换类型。

可选
width
是一个非负十进制整数,表明要向输出中写入的最少字符数。

可选
precision
是一个非负十进制整数,通常用来限制字符数。特定行为取决于转换类型。

所需
conversion
是一个表明应该如何格式化参数的字符。给定参数的有效转换集取决于参数的数据类型。

argument_index很好理解,就是一参数占位符,用来表示要被格式化的参数。

flags

标志

常规

字符

整数

浮点

日期/时间

说明

'-'

y

y

y

y

y

结果将是左对齐的。

'#'

y1

-

y3

y

-

结果应该使用依赖于转换类型的替换形式

'+'

-

-

y4

y

-

结果总是包括一个符号

' '

-

-

y4

y

-

对于正值,结果中将包括一个前导空格

'0'

-

-

y

y

-

结果将用零来填充

','

-

-

y2

y5

-

结果将包括特定于语言环境的组分隔符

'('

-

-

y4

y5

-

结果将是用圆括号括起来的负数

1 取决于Formattable
的定义。

2 只适用于 'd'转换。

3 只适用于 'o'、'x'和'X'转换。

4 对 BigInteger 应用 'd'、'o'、'x'和'X'转换时,或者对byte及Byte、short及Short、int及Integer、long及Long
分别应用 'd' 转换时适用。

5 只适用于 'e'、'E'、'f'、'g'和'G'转换。

任何未显式定义为标志的字符都是非法字符,并且都被保留,以供扩展使用。

width 就表示一最少字符数,被格式化参数用precision 截取器截取后与width 相比,被格式化参数字符数如果小于width ,则加字符则到等于width 。如果大于则width 不起作用。所以可以叫width 为少加多过器。

precision 在上面也提到了,precision 是一个截取器,用于截取被格式化参数。

conversion 转换可分为以下几类:

 常规-可应用于任何参数类型

 字符-可应用于表示Unicode字符的基本类型:char、Character、byte、Byte、short和Short。当Character.isValidCodePoint(int)
返回 true时,可将此转换应用于 int和Integer
类型

数值

1整数-可应用于Java的整数类型:byte、Byte、short、Short、int、Integer、long、Long
BigInteger

2浮点-可用于Java的浮点类型:float、Float、double、Double
BigDecimal

 日期/时间-可应用于Java的、能够对日期或时间进行编码的类型:long、LongCalendar
Date

 百分比-产生字面值'%' ('\u0025')

 行分隔符-产生特定于平台的行分隔符

常规

B b

如果参数arg 为 null,则结果为 "false"。如果arg
是一个 boolean 值或Boolean,则结果为String.valueOf()
返回的字符串。否则结果为 "true"。

H h

如果参数arg 为 null,则结果为 "null"。否则,结果为调用Integer.toHexString(arg.hashCode())
得到的结果。

S s

如果参数arg 为 null,则结果为 "null"。如果arg
实现 Formattable,则调用arg.formatTo。否则,结果为调用
arg.toString() 得到的结果。

字符

C c

结果是一个 Unicode字符

整数

d

结果被格式化为十进制整数

o

结果被格式化为八进制整数

X x

结果被格式化为十六进制整数

浮点

E e

结果被格式化为用计算机科学记数法表示的十进制数

f

结果被格式化为十进制数

G g

根据精度和舍入运算后的值,使用计算机科学记数形式或十进制格式对结果进行格式化。

A a

结果被格式化为带有效位数和指数的十六进制浮点数

日期,日间

T t

日期和时间转换字符的前缀

百分比

%

结果为字面值 '%'

行分隔符

n

结果为特定于平台的行分隔符

常出现的异常

java.util.IllegalFormatConversionException: d != java.lang.Double
: 被格式化参数类型与规则转换类型不对应。

java.util.FormatFlagsConversionMismatchException: Conversion = d, Flags = #  : flag不适用于规则转换类型。

Formatter类是用正则表达式验证给定规则的

正则表达式如下:

private static final
String formatSpecifier

=

"%(\\d+\\$)?([-#+0,(\\<]*)?(\\d+)?(\\.\\d+)?([tT])?([a-zA-Z%])";

总结:

  •    最重要的是它可以格式化日期/时间,数值和字符。
  •    可以把日期转换成年,月,日,星期等。可以为数值填充空格或0,添加分组字符,正负号,及小括号。我们可以在System.out.format   
    (),String.format()方法中直接应用Formatter类。

下面贴一段代码,将Android中的播放器的进度值之转换为相应的时间

/**
* 格式化的格式
*/
private StringBuilder sFormatBuilder = new StringBuilder();
/**
* 格式化类
*/
private Formatter sFormatter = new Formatter(sFormatBuilder, Locale.getDefault());
/**
* 格式化的相关属性
*/
private final Object[] sTimeArgs = new Object[3];
/**
* 转换进度值为时间
* @param secs
* @return
*/
private String makeTimeString(int secs) {
/**
* %[argument_index$][flags][width]conversion
* 可选的 argument_index 是一个十进制整数,用于表明参数在参数列表中的位置。第一个参数由 "1$" 引用,第二个参数由 "2$" 引用,依此类推。
可选 flags 是修改输出格式的字符集。有效标志集取决于转换类型。
可选 width 是一个非负十进制整数,表明要向输出中写入的最少字符数。
可选 precision 是一个非负十进制整数,通常用来限制字符数。特定行为取决于转换类型。
所需 conversion 是一个表明应该如何格式化参数的字符。给定参数的有效转换集取决于参数的数据类型。
*/
String durationformat = getString(R.string.durationformat);//<xliff:g id="format">%1$02d:%2$02d:%3$02d</xliff:g>
sFormatBuilder.setLength(0);
secs = secs / 1000;
Object[] timeArgs = sTimeArgs;
timeArgs[0] = secs / 3600; //时
timeArgs[1] = (secs % 3600) / 60; //分
timeArgs[2] = (secs % 3600 % 60) % 60; //秒
return sFormatter.format(durationformat, timeArgs).toString().trim();
}

其中R.string.durationformat定义如下:

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="durationformat" translatable="false"><xliff:g id="format">%1$02d:%2$02d:%3$02d</xliff:g></string>
</resources>

关于格式化时间,还可以参考我的博客

《我的Java开发学习之旅------>工具类:将播放器的进度值转换成相应的时间格式》

地址:http://blog.csdn.net/ouyang_peng/article/details/17164255

什么是xliff?可以参考http://baike.baidu.com/view/4160854.htm

====================================================================================

  作者:欧阳鹏  欢迎转载,与人分享是进步的源泉!

  转载请保留原文地址:http://blog.csdn.net/ouyang_peng

====================================================================================

我的Java开发学习之旅------>Java 格式化类(java.util.Formatter)基本用法的更多相关文章

  1. 我的Java开发学习之旅------>工具类:将播放器的进度值转换成相应的时间格式

    在我的博客<我的Java开发学习之旅------>Java 格式化类(java.util.Formatter)基本用法,地址:http://blog.csdn.net/ouyang_pen ...

  2. 我的Java开发学习之旅------>在Dos环境下Java内部类的编译和运行

    习惯了在IDE工具上进行代码编写,连最基本的Javac命令和Java命令都忘记的差不多了,今天对一个Java内部类进行编译和运行的时候,就出糗了.IDE是把双刃剑,它可以什么都帮你做了,你只要敲几行代 ...

  3. 我的Java开发学习之旅------>Java NIO 报java.nio.charset.MalformedInputException: Input length = 1异常

    今天在使用Java NIO的Channel和Buffer进行文件操作时候,报了java.nio.charset.MalformedInputException: Input length = 1异常, ...

  4. 我的Java开发学习之旅------>工具类:Java获取字符串和文件进行MD5值

    ps:这几天本人用百度云盘秒传了几部大片到云盘上,几个G的文件瞬秒竟然显示"上传成功"!这真让我目瞪口呆,要是这样的话,那得多快的网速,这绝对是不可能的,也许这仅是个假象.百度了一 ...

  5. 我的Java开发学习之旅------>工具类:Java使用正则表达式分离出字符串中的中文和英文

    今天看到一个工具类使用正则表达式将一大段字符串中的中文和英文都分离出来了,在此记录一下,读者可以收藏! import java.util.ArrayList; import java.util.Col ...

  6. 我的Java开发学习之旅------&gt;Base64的编码思想以及Java实现

    Base64是一种用64个字符来表示随意二进制数据的方法. 用记事本打开exe.jpg.pdf这些文件时,我们都会看到一大堆乱码,由于二进制文件包括非常多无法显示和打印的字符.所以,假设要让记事本这种 ...

  7. 我的Java开发学习之旅------>Java利用Comparator接口对多个排序条件进行处理

    一需求 二实现Comparator接口 三验证排序结果 验证第一条件首先按级别排序级别最高的排在前面 验证第二条如果级别相等那么按工资排序工资高的排在前面 验证第三条如果工资相当则按入职年数排序入职时 ...

  8. 我的Java开发学习之旅------>Base64的编码思想以及Java实现

    Base64是一种用64个字符来表示任意二进制数据的方法. 用记事本打开exe.jpg.pdf这些文件时,我们都会看到一大堆乱码,因为二进制文件包含很多无法显示和打印的字符,所以,如果要让记事本这样的 ...

  9. 我的Java开发学习之旅------>System.nanoTime与System.currentTimeMillis的区别

    首先来看一道题:下面代码的输出结果是什么? import java.util.HashMap; import java.util.Map; public class HashMapTest { pub ...

随机推荐

  1. Datatable和实体还有实体集List的差别与转化

    机房收费系统大家想必不是做完.就是已经在手上了,在一開始做的时候就明白规定.我们必须用实体.而不能使Datatable,由于说是Datatable直接面向了数据库,当时不是非常明白,于是也没有再深究, ...

  2. HTML5 Canvas 龟羊赛跑

    从一张图上截取不同图块,动态显示在canvas上,形成赛跑的效果.完整代码图片下载请点击 https://files.cnblogs.com/files/xiandedanteng/turtleShe ...

  3. 使用C++11的function/bind组件封装Thread以及回调函数的使用

    之前在http://www.cnblogs.com/inevermore/p/4008572.html中采用面向对象的方式,封装了Posix的线程,那里采用的是虚函数+继承的方式,用户通过重写Thre ...

  4. react 打包后,项目部署完毕,刷新页面报错(404)

    原因解析: 之所以你在浏览器内可以由首页跳转到其他路由地址,是因为这是由前端自行渲染的,你在React Router定义了对应的路由,脚本并没有刷新网页访问后台,是JS动态更改了location. 当 ...

  5. Acceptor-Connector模式一(Acceptor的工作)V2.0

    前言:ACE Acceptor-Connector模式 首先这样的模式肯定是面向连接的TCP/IP协议. 无论是什么场景.差点儿面向连接的通信程序总是由一端主动发起连接,一端监听等待对方的连接. 这就 ...

  6. Url Scheme实现APP间通信、分享

    代码地址如下:http://www.demodashi.com/demo/12748.html 简介: URL Scheme就是一个可以让app相互之间可以跳转的对外接口.通过给APP定义一个唯一的U ...

  7. Android 冷兵器 之 tools

    代码地址如下:http://www.demodashi.com/demo/12612.html 前言 Android开发在所难免的就是UI的预览和调整,一般情况下都是直接run看效果,或者是使用AS的 ...

  8. IOS7下,AVAudioRecorder需要注意的一点

    iOs7下,使用AVAudioRecorder录音的时候,会在顶部出现一个红框,或者红框一闪而过,这时候需要设置AVAudioSession,如下代码: AVAudioSession * sessio ...

  9. PHP面试题及答案解析(2)—PHP面向对象

    1. 写出 php 的 public.protected.private 三种访问控制模式的区别. public:公有,任何地方都可以访问protected:继承,只能在本类或子类中访问,在其它地方不 ...

  10. svn client命令

    经常使用svn命令说明 1.从SVN仓库中检索出代码到工作拷贝: # svn checkout https://svn.sinaapp.com/appname [workcopy] 当中workcop ...