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 |
} |