留个纪念。这个类主要用于将数字金额转换成中文大写金额,提供了三个方法:
- toDX(double val)
- toDX(String val)
- toDX(int val)
使用方法
AmtInWords.getIns().toDX(val);
import java.text.DecimalFormat;
/**
* The <code>AmtInWords</code> class is used to convert the
* amount of the amount to the capital amount.The amount is
* accurate to two decimal numbers.The maximum range is one
* trillion.For example:
* <p><blockquote><pre>
* How "10,001.11" convert to "壹万零壹元壹角壹分" ?
* String amt = "10,001";
* String result = AmtInWords.getIns().toDX(amt);
* </pre></blockquote></p>
*
* @author zou_bbei
* @version 1.0
*/
public class AmtInWords {
/** The hungry man type single model */
private static AmtInWords ins = new AmtInWords();
/** Prevent new object */
private AmtInWords(){}
/** get a {@code AmtInWords} instance by the single*/
public static AmtInWords getIns(){
return ins;
}
/**
* Receive the {@code String} type of {@code val}.
* Return the {@code String} type Chinese capital amount.
* @param val
* @return
*/
public String toDX(String val){
if(checkIsNull(val)){
return cont.ZERO.get()+cont.YUAN.get()+cont.ZHENG.get();
}
val = val.replace(",", "");
val = convert(val);
return val;
}
/**
* Receive the {@code double} type of {@code val}.
* Return the {@code String} type Chinese capital amount.
* @param val
* @return
*/
public String toDX(double val){
DecimalFormat df = new DecimalFormat("0.00");
return toDX(df.format(val));
}
/**
* Receive the {@code int} type of {@code val}.
* Return the {@code String} type Chinese capital amount.
* @param val
* @return
*/
public String toDX(int val){
return toDX(String.valueOf(val));
}
/*******************************************************/
/*****************private method***********************/
/******************************************************/
/**
* The <code>convert</code> method is the core
* method of conversion.
* Divide the amount into two parts: integers and decimal parts.
* @param val
* @return
*/
private String convert(String val) {
//check null
if(checkIsNull(val)){
return cont.ZERO.get()+cont.YUAN.get()+cont.ZHENG.get();
}
String ret = "";//the return value
String[] temp = null;
String integers = "";//the integers part
String decimals = "";//the decimal part
//If has decimal part
if(val.contains(".")){
temp = val.split("\\.");
integers = temp[0];
decimals = temp[1];
}else{
integers = val;
}
//The integers conversion
integers = convertInt(integers);
//The decimal conversion
decimals = convertDec(decimals);
ret = getDX(integers, decimals);
return ret;
}
/**
* Get a Chinese capital amount
* @param integers
* integral part value
* @param decimals
* decimal part value
* @return
*/
private String getDX(String integers, String decimals) {
String ret = "";
if(checkIsNull(integers) && checkIsNull(decimals)){
ret = cont.ZERO.get()+cont.YUAN.get()+cont.ZHENG.get();
}else if(!checkIsNull(integers) && checkIsNull(decimals)){
//The decimal conversion
ret = integers + cont.YUAN.get() + cont.ZHENG.get();
}else if(checkIsNull(integers) && !checkIsNull(decimals)){
ret = decimals.indexOf(cont.ZERO.get()) == 0?decimals.substring(1, decimals.length()):decimals;
}else{
ret = integers + cont.YUAN.get() + decimals;
}
return ret;
}
/**>>>>>>>>Decimal part processing logic>>>>>>>>>>>>>>>>>**/
/**
* Decimal part conversion, only limited to two decimal.
* @param dec
* @return
*/
private String convertDec(String dec) {
if(checkIsNull(dec)){
return "";
}
char[] decs = dec.toCharArray();
//conversion
String jiao = jiaoAndFen(decs[0], 0);
String fen = jiaoAndFen(decs[1], 1);
//split joint
String zero = cont.ZERO.get();
if(zero.equals(jiao) && zero.equals(fen)){
return "";
}else if(!zero.equals(jiao) && zero.equals(fen) ){
dec = jiao;
}else{
dec = jiao + fen;
}
return dec;
}
/**
* The <code>jiaoAndFen</code> method is used for
* the conversion of jiao and fen.
* <p>if flag == 0, for jiao</p>
* <p>if flag == 1, for fen</p>
* @param c
* @return
*/
private String jiaoAndFen(char c,int flag) {
String ret = "";
String unit = "";
if(0 == flag){
unit = cont.JIAO.get();
}else{
unit = cont.FEN.get();
}
switch(c){
case '0':
ret = cont.ZERO.get();
break;
case '1':
ret = cont.ONE.get() + unit;
break;
case '2':
ret = cont.TWO.get() + unit;
break;
case '3':
ret = cont.THREE.get() + unit;
break;
case '4':
ret = cont.FOUR.get() + unit;
break;
case '5':
ret = cont.FIVE.get() + unit;
break;
case '6':
ret = cont.SIX.get() + unit;
break;
case '7':
ret = cont.SEVEN.get() + unit;
break;
case '8':
ret = cont.EIGHT.get() + unit;
break;
case '9':
ret = cont.NINE.get() + unit;
break;
}
return ret;
}
/**<<<<<<<<<<<Decimal part processing logic<<<<<<<<<<<<<<<<**/
/**>>>>>>>>>>Integer part processing logic>>>>>>>>>>>>>>>>>**/
/**
* Integers part conversion.
* @param integers
* @return
*/
private String convertInt(String integers) {
//the return value
StringBuffer ret = new StringBuffer();
char[] integerss = integers.toCharArray();
int digit = 0;
//the range : 0~10,000
int zeros_0 = 0;
StringBuffer val_0 = new StringBuffer();
//the range : 10,000~100,000,000
int zeros_1 = 0;
StringBuffer val_1 = new StringBuffer();
//the range : 100,000,000~1000,000,000,000
int zeros_2 = 0;
StringBuffer val_2 = new StringBuffer();
//the range : 1000,000,000,000~10^17
int zeros_3 = 0;
StringBuffer val_3 = new StringBuffer();
for(int i = integerss.length; i>0; i--){
digit++;
char c_num = integerss[i-1];//get number
if(digit < 5){
if('0' == c_num){
zeros_0++;
continue;
}
val_0 = join(val_0, c_num, digit, zeros_0);
zeros_0 = 0;//resetting
}
if(digit >= 5 && digit < 9){
if('0' == c_num){
zeros_1++;
continue;
}
val_1 = join(val_1, c_num, digit, zeros_1);
zeros_1 = 0;
}
if(digit >= 9 && digit < 13){
if('0' == c_num){
zeros_2++;
continue;
}
val_2 = join(val_2, c_num, digit, zeros_2);
zeros_2 = 0;
}
if(digit >= 13 && digit < 17){
if('0' == c_num){
zeros_3++;
continue;
}
val_3 = join(val_3, c_num, digit, zeros_3);
zeros_3 = 0;
}
}
val_0 = deleteZero(val_0);
if(val_1.length() > 0){
val_1 = deleteZero(val_1);
val_1.append(
!checkIsNull(val_0.toString()) && zeros_0 != 0 ?
cont.WL.get():cont.W.get());
}
if(val_2.length() > 0){
val_2 = deleteZero(val_2);
val_2.append((!checkIsNull(val_0.toString()) && checkIsNull(val_1.toString()))
|| (!checkIsNull(val_1.toString()) && zeros_1 != 0)?
cont.YL.get(): cont.Y.get());
}
if(val_3.length() > 0){
val_3 = deleteZero(val_3);
val_3.append(((!checkIsNull(val_0.toString()) || !checkIsNull(val_1.toString())) && checkIsNull(val_2.toString()))
|| (!checkIsNull(val_2.toString()) && zeros_2 != 0)? cont.ZL.get(): cont.Z.get());
}
ret.append(val_3).append(val_2).append(val_1).append(val_0);
return ret.toString();
}
/**
* Delete superfluous zero
* @param val
* @return
*/
private StringBuffer deleteZero(StringBuffer val) {
if(val.length() == 0){
return val;
}
int big = val.length()-1;
if(val.lastIndexOf(cont.ZERO.get()) == val.length()-1 ){
val =new StringBuffer(val.toString().substring(0, big));
}
return val;
}
/**
* Splice return value
*
* @param val
* the return value
* @param c_num
* char type numbers
* @param digit
* the digit
* @param zeros
* the number of zero
* @return
*/
private StringBuffer join(StringBuffer val,char c_num, int digit, int zeros){
StringBuffer sb = new StringBuffer(spliceIntegers(c_num, digit, zeros));
val = sb.append(val);
return val;
}
/**
* splice integers
*
* @param c_num
* char type numbers
* @param digit
* the digit
* @param zeros
* the number of zero
* @return
*/
private String spliceIntegers(char c_num, int digit, int zeros) {
String ret = "";
ret = numToDX(c_num);
ret += appendDW(digit);
ret += appendZERO(zeros);
return ret;
}
/**
* Add Chinese zero
*
* @param zeros
* the number of zero
* @return
*/
private String appendZERO(int zeros) {
String ret = "";
if(zeros != 0){
ret = cont.ZERO.get();
}
return ret;
}
/**
* Add Chinese digit
*
* @param digit
* @return
*/
private String appendDW(int digit) {
String ret = "";
switch(digit){
case 1:
break;
case 2:
case 6:
case 10:
ret = cont.TEN.get();
break;
case 3:
case 7:
case 11:
ret = cont.B.get();
break;
case 4:
case 8:
case 12:
ret = cont.Q.get();
break;
}
return ret;
}
/**
* Add Chinese number
*
* @param c_num
*
* @return
*/
private String numToDX(char c_num) {
String ret = "";
switch(c_num){
case '1':
ret = cont.ONE.get();
break;
case '2':
ret = cont.TWO.get();
break;
case '3':
ret = cont.THREE.get();
break;
case '4':
ret = cont.FOUR.get();
break;
case '5':
ret = cont.FIVE.get();
break;
case '6':
ret = cont.SIX.get();
break;
case '7':
ret = cont.SEVEN.get();
break;
case '8':
ret = cont.EIGHT.get();
break;
case '9':
ret = cont.NINE.get();
break;
}
return ret;
}
/**<<<<<<<<<<<<<Integer part processing logic<<<<<<<<<<<<<**/
/**
* constant
*
* @author zou_bbei
*
*/
private enum cont{
ZERO("零"),ONE("壹"),TWO("贰"),THREE("叁"),FOUR("肆"),FIVE("伍"),
SIX("陆"),SEVEN("柒"),EIGHT("捌"),NINE("玖"),TEN("拾"),
B("佰"),Q("仟"),W("万"),WL("万零"),Y("亿"),YL("亿零"),Z("兆"),ZL("兆零"),
FEN("分"),JIAO("角"),ZHENG("整"),YUAN("元")
;
private String context;
private cont(String context){
this.context = context;
}
public String get(){
return context;
}
}
/**
* Check null. If is null, return {@code true}.
* If not is null, return {@code false}
* @param val
* @return
*/
private boolean checkIsNull(String val){
return val == null || "".equals(val);
}
}