1 | class MoneyFormat{ |
002 | private final String [] pattern ={ "零" , "壹" , "贰" , "叁" , "肆" , "伍" , "陆" , "柒" , "捌" , "玖" }; |
003 | private final String [] cPattern ={ "" , "拾" , "佰" , "仟" , "万" , "拾" , "佰" , "仟" , "亿" }; |
004 | private final String [] cfPattern = { "" , "角" , "分" }; |
005 | private final String ZEOR = "零" ; |
006 | public MoneyFormat(){ |
007 | System.out.println( "run..." ); |
008 | |
009 | } |
010 | |
011 | public String format(String moneyString){ |
012 | int dotPoint = moneyString.indexOf( "." ); //判断是否为小数 |
013 | String moneyStr; |
014 | if (dotPoint != - 1 ){ |
015 | moneyStr = moneyString.substring( 0 ,moneyString.indexOf( "." )); |
016 | } |
017 | else { |
018 | moneyStr = moneyString; |
019 | } |
020 | StringBuffer fraction = null ; //小数部分的处理,以及最后的yuan. |
021 | StringBuffer ms = new StringBuffer(); |
022 | for ( int i = 0 ;i < moneyStr.length();i++){ |
023 | ms.append(pattern[moneyStr.charAt(i) - 48 ]); //按数组的编号加入对应大写汉字 |
024 | } |
025 | |
026 | int cpCursor = 1 ; |
027 | for ( int j = moneyStr.length() - 1 ;j > 0 ;j--){ |
028 | ms.insert(j,cPattern[cpCursor]); //在j之后加字符,不影响j对原字符串的相对位置 |
029 | //只是moneyStr.length()不断增加 |
030 | //insert(j,"string")就在j位置处插入,j=0时为第一位 |
031 | cpCursor = cpCursor == 8 ? 1 :cpCursor + 1 ; //亿位之后重新循环 |
032 | } |
033 | |
034 | |
035 | while (ms.indexOf( "零拾" ) != - 1 ){ //当十位为零时用一个"零"代替"零拾" |
036 | //replace的起始于终止位置 |
037 | ms.replace(ms.indexOf( "零拾" ),ms.indexOf( "零拾" ) + 2 ,ZEOR); |
038 | } |
039 | while (ms.indexOf( "零佰" ) != - 1 ){ //当百位为零时,同理 |
040 | ms.replace(ms.indexOf( "零佰" ),ms.indexOf( "零佰" ) + 2 ,ZEOR); |
041 | } |
042 | while (ms.indexOf( "零仟" ) != - 1 ){ //同理 |
043 | ms.replace(ms.indexOf( "零仟" ),ms.indexOf( "零仟" ) + 2 ,ZEOR); |
044 | } |
045 | while (ms.indexOf( "零万" ) != - 1 ){ //万需保留,中文习惯 |
046 | ms.replace(ms.indexOf( "零万" ),ms.indexOf( "零万" ) + 2 , "万" ); |
047 | } |
048 | while (ms.indexOf( "零亿" ) != - 1 ){ //同上 |
049 | ms.replace(ms.indexOf( "零亿" ),ms.indexOf( "零亿" ) + 2 , "亿" ); |
050 | } |
051 | while (ms.indexOf( "零零" ) != - 1 ){ //有连续数位出现零,即有以下情况,此时根据习惯保留一个零即可 |
052 | ms.replace(ms.indexOf( "零零" ),ms.indexOf( "零零" ) + 2 ,ZEOR); |
053 | } |
054 | while (ms.indexOf( "亿万" ) != - 1 ){ //特殊情况,如:100000000,根据习惯保留高位 |
055 | ms.replace(ms.indexOf( "亿万" ),ms.indexOf( "亿万" ) + 2 , "亿" ); |
056 | } |
057 | while (ms.lastIndexOf( "零" ) == ms.length()- 1 ){ //当结尾为零j,不必显示,经过处理也只可能出现一个零 |
058 | if (ms.indexOf( "零" ) == - 1 ){ |
059 | ms.delete(ms.lastIndexOf( "零" ),ms.lastIndexOf( "零" ) + 1 ); |
060 | } else { |
061 | break ; |
062 | } |
063 | } |
064 | |
065 | |
066 | int end; |
067 | if ((dotPoint = moneyString.indexOf( "." )) != - 1 ){ //是小数的进入 |
068 | String fs = moneyString.substring(dotPoint + 1 ,moneyString.length()); |
069 | if (fs.indexOf( "00" ) == - 1 || fs.indexOf( "00" ) >= 2 ){ //若前两位小数全为零,则跳过操作 |
070 | end = fs.length() > 2 ? 2 :fs.length(); //仅保留两位小数 |
071 | fraction = new StringBuffer(fs.substring( 0 ,end)); |
072 | for ( int j = 0 ;j < fraction.length();j++){ |
073 | fraction.replace(j,j+ 1 , this .pattern[fraction.charAt(j) - 48 ]); //替换大写汉字 |
074 | } |
075 | for ( int i = fraction.length();i > 0 ;i--){ //插入中文标识 |
076 | fraction.insert(i,cfPattern[i]); |
077 | } |
078 | fraction.insert( 0 , "元" ); //为整数部分添加标识 |
079 | } |
080 | else { |
081 | fraction = new StringBuffer( "元整" ); |
082 | } |
083 | |
084 | } |
085 | else { |
086 | fraction = new StringBuffer( "元整" ); |
087 | } |
088 | |
089 | ms.append(fraction); //加入小数部分 |
090 | return ms.toString(); |
091 | } |
092 | |
093 | |
094 | |
095 | |
096 | public static void main(String [] ar){ |
097 | System.out.println( new MoneyFormat().format( "10005022.123009" )); |
098 | System.out.println( new MoneyFormat().format( "0.12" )); |
099 | } |
100 | } |
上面是第一种方法,简单些,容易理解,下面这种复杂点,两个方法都可以实现这个功能
001 | public class MoneyUtil { |
002 | |
003 | public static String[] chineseDigits = new String[] { "零" , "壹" , "贰" , "叁" , "肆" , "伍" , "陆" , "柒" , "捌" , "玖" }; |
004 | |
005 | /** |
006 | * 把金额转换为汉字表示的数量,小数点后四舍五入保留两位 |
007 | * @param amount |
008 | * @return |
009 | */ |
010 | public static String amountToChinese( double amount) { |
011 | |
012 | if (amount > 99999999999999.99 || amount < - 99999999999999.99 ) |
013 | throw new IllegalArgumentException( "参数值超出允许范围 (-99999999999999.99 ~ 99999999999999.99)!" ); |
014 | |
015 | boolean negative = false ; |
016 | if (amount < 0 ) { |
017 | negative = true ; |
018 | amount = amount * (- 1 ); |
019 | } |
020 | |
021 | long temp = Math.round(amount * 100 ); |
022 | int numFen = ( int )(temp % 10 ); // 分 |
023 | temp = temp / 10 ; |
024 | int numJiao = ( int )(temp % 10 ); //角 |
025 | temp = temp / 10 ; |
026 | //temp 目前是金额的整数部分 |
027 | |
028 | int [] parts = new int [ 20 ]; // 其中的元素是把原来金额整数部分分割为值在 0~9999 之间的数的各个部分 |
029 | int numParts = 0 ; // 记录把原来金额整数部分分割为了几个部分(每部分都在 0~9999 之间) |
030 | for ( int i= 0 ; ; i++) { |
031 | if (temp == 0 ) |
032 | break ; |
033 | int part = ( int )(temp % 10000 ); |
034 | parts[i] = part; |
035 | numParts ++; |
036 | temp = temp / 10000 ; |
037 | } |
038 | |
039 | boolean beforeWanIsZero = true ; // 标志“万”下面一级是不是 0 |
040 | |
041 | String chineseStr = "" ; |
042 | for ( int i= 0 ; i<numParts; i++) { |
043 | |
044 | String partChinese = partTranslate(parts[i]); |
045 | if (i % 2 == 0 ) { |
046 | if ( "" .equals(partChinese)) |
047 | beforeWanIsZero = true ; |
048 | else |
049 | beforeWanIsZero = false ; |
050 | } |
051 | |
052 | if (i != 0 ) { |
053 | if (i % 2 == 0 ) |
054 | chineseStr = "亿" + chineseStr; |
055 | else { |
056 | if ( "" .equals(partChinese) && !beforeWanIsZero) // 如果“万”对应的 part 为 0,而“万”下面一级不为 0,则不加“万”,而加“零” |
057 | chineseStr = "零" + chineseStr; |
058 | else { |
059 | if (parts[i- 1 ] < 1000 && parts[i- 1 ] > 0 ) // 如果"万"的部分不为 0, 而"万"前面的部分小于 1000 大于 0, 则万后面应该跟“零” |
060 | chineseStr = "零" + chineseStr; |
061 | chineseStr = "万" + chineseStr; |
062 | } |
063 | } |
064 | } |
065 | chineseStr = partChinese + chineseStr; |
066 | } |
067 | |
068 | if ( "" .equals(chineseStr)) // 整数部分为 0, 则表达为"零元" |
069 | chineseStr = chineseDigits[ 0 ]; |
070 | else if (negative) // 整数部分不为 0, 并且原金额为负数 |
071 | chineseStr = "负" + chineseStr; |
072 | |
073 | chineseStr = chineseStr + "元" ; |
074 | |
075 | if (numFen == 0 && numJiao == 0 ) { |
076 | chineseStr = chineseStr + "整" ; |
077 | } |
078 | else if (numFen == 0 ) { // 0 分,角数不为 0 |
079 | chineseStr = chineseStr + chineseDigits[numJiao] + "角" ; |
080 | } |
081 | else { // “分”数不为 0 |
082 | if (numJiao == 0 ) |
083 | chineseStr = chineseStr + "零" + chineseDigits[numFen] + "分" ; |
084 | else |
085 | chineseStr = chineseStr + chineseDigits[numJiao] + "角" + chineseDigits[numFen] + "分" ; |
086 | } |
087 | |
088 | return chineseStr; |
089 | |
090 | } |
091 | |
092 | |
093 | /** |
094 | * 把一个 0~9999 之间的整数转换为汉字的字符串,如果是 0 则返回 "" |
095 | * @param amountPart |
096 | * @return |
097 | */ |
098 | private static String partTranslate( int amountPart) { |
099 | |
100 | if (amountPart < 0 || amountPart > 10000 ) { |
101 | throw new IllegalArgumentException( "参数必须是大于等于 0,小于 10000 的整数!" ); |
102 | } |
103 | |
104 | |
105 | String[] units = new String[] { "" , "拾" , "佰" , "仟" }; |
106 | |
107 | int temp = amountPart; |
108 | |
109 | String amountStr = new Integer(amountPart).toString(); |
110 | int amountStrLength = amountStr.length(); |
111 | boolean lastIsZero = true ; //在从低位往高位循环时,记录上一位数字是不是 0 |
112 | String chineseStr = "" ; |
113 | |
114 | for ( int i= 0 ; i<amountStrLength; i++) { |
115 | if (temp == 0 ) // 高位已无数据 |
116 | break ; |
117 | int digit = temp % 10 ; |
118 | if (digit == 0 ) { // 取到的数字为 0 |
119 | if (!lastIsZero) //前一个数字不是 0,则在当前汉字串前加“零”字; |
120 | chineseStr = "零" + chineseStr; |
121 | lastIsZero = true ; |
122 | } |
123 | else { // 取到的数字不是 0 |
124 | chineseStr = chineseDigits[digit] + units[i] + chineseStr; |
125 | lastIsZero = false ; |
126 | } |
127 | temp = temp / 10 ; |
128 | } |
129 | return chineseStr; |
130 | } |
131 | |
132 | |
133 | |
134 | public static void main(String[] args) { |
135 | |
136 | if (args.length == 0 ) { |
137 | System.out.println( "转换演示:" ); |
138 | System.out.println( "-------------------------" ); |
139 | System.out.println( "0000000000000000001.01: " + amountToChinese( 0000000000000000001.01 )); |
140 | System.out.println( "45689263.626: " + amountToChinese( 45689263.626 )); |
141 | System.out.println( "0.69457: " + amountToChinese( 0.69457 )); |
142 | System.out.println( "253.0: " + amountToChinese( 253.0 )); |
143 | System.out.println( "0: " + amountToChinese( 0 )); |
144 | System.out.println( "-------------------------" ); |
145 | |
146 | System.out.println( "999: " + amountToChinese( 999 )); |
147 | |
148 | //System.out.println(Long.MAX_VALUE); |
149 | //System.out.println(Long.MIN_VALUE); |
150 | } |
151 | else { |
152 | System.out.println( "转换结果:" ); |
153 | System.out.println(args[ 0 ] + ": " + amountToChinese(Double.parseDouble(args[ 0 ]))); |
154 | } |
155 | |
156 | } |
157 | |
158 | } |
http://www.open-open.com/lib/view/open1400206687504.html