阿拉伯数字转人民币汉字算法实现

时间:2022-12-15 00:49:12
一、需求描述

    在我们日常开发过程中,在和金额相关的业务打交道的时候经常需要把阿拉伯数字金额装换为大写的金额(例如:壹佰圆整)。本人最经也正好也有这个需求,故整理了一个简单的转换算法。

二、算法实现
 

/**
* 金额转为大写金额工具类
*
* @date: 2023/02/02 09:08
*/
public class MoneyChangeUtil {

private static final String digit_single = "零壹贰叁肆伍陆柒捌玖";

private static final String[] digit_ten = {"", "拾", "佰", "仟"};

private static final String[] digit_billion = {"", "万", "亿", "万亿", "亿亿"};

/** 数字转化成整数 */
private static String changeDigit(String rmbNum) {
StringBuilder rmbBuilder = new StringBuilder();
int point = rmbNum.indexOf('.');
// 判断是否为小数还是整数,长度小于零为整数
if (point < 0) {
point = rmbNum.length();
}
// 获取整数部分
String integer = rmbNum.substring(0, point);
rmbBuilder.append(changeInteger(Long.parseLong(integer)));
// 处理小数部分
if (point != rmbNum.length()) {
rmbBuilder.append("点");
// 获取小数点后所有数
String decimal = rmbNum.substring(point + 1);
for (int i = 0; i < decimal.length(); i++) {

rmbBuilder.append(digit_single.charAt(Integer.parseInt(decimal.substring(i, i + 1))));
}
}
String rmb = rmbBuilder.toString();
// 处理特殊情况,可能不全
if (rmb.startsWith("零")) {
rmb = rmb.substring(1);
}
if (rmb.startsWith("一十")) {
rmb = rmb.substring(1);
}
while (rmb.endsWith("零")) {
rmb = rmb.substring(0, rmb.length() - 1);
}
if (rmb.startsWith("点")) {
rmb = "零" + rmb;
}
if (rmb.endsWith("点")) {
rmb = rmb.substring(0, rmb.length() - 1);
}
return rmb;
}

/** 位数小于4时,调用处理数据 */
private static String readNumber(String rmb) {
StringBuilder rmbBuilder = new StringBuilder();
if (rmb.length() != 4) {
return null;
}
for (int i = 0; i < 4; i++) {
char ch = rmb.charAt(i);
if (ch == '0' && i > 1 && rmb.charAt(i - 1) == '0') {
continue;
}
if (ch != '0' && i > 1 && rmb.charAt(i - 1) == '0') {
rmbBuilder.append('零');
}
if (ch != '0') {

rmbBuilder.append(digit_single.charAt(ch - 48));
rmbBuilder.append(digit_ten[4 - i - 1]);
}
}
return rmbBuilder.toString();
}

/** 整数部分转换大写 */
private static String changeInteger(long lon) {
StringBuilder RmbBuilder = new StringBuilder();
// 增加3位数,为了完成大写转换
String add = "000" + lon;
int length = add.length() / 4;
// 根据不同的位数长度,消除add"0"的个数
add = add.substring(add.length() - length * 4);
for (int i = 0; i < length; i++) {
String RmbNumber = add.substring(i * 4, i * 4 + 4);
String readNumber = readNumber(RmbNumber);
RmbBuilder.append(readNumber);
if (readNumber.length() != 0) {
RmbBuilder.append(digit_billion[length - i - 1]);
}
}
String RMB = new String(RmbBuilder);
if (RMB.length() != 0 && RMB.startsWith("零")) {
RMB = RMB.substring(1);
}
return RMB;
}

/** 人名币输出格式 */
public static String changeNumberRMB(double rmbNumber) {
String rmb = String.valueOf(rmbNumber);
DecimalFormat decimalFormat = new DecimalFormat("#.#");
decimalFormat.setMaximumFractionDigits(2);
// true人民币大写,并返回数据
rmb = changeDigit(rmb);
// 将壹拾元转为拾元
if (rmb.indexOf("壹拾") == 0) {
rmb = rmb.replace("壹拾", "拾");
}
if (rmb.indexOf('点') >= 0) {
rmb = rmb + "零";
rmb = rmb.replaceAll("点", "元");
String integer = rmb.substring(0, rmb.indexOf('元') + 1);
String decimal = rmb.substring(rmb.indexOf('元') + 1);
rmb = integer + decimal.charAt(0) + "角" + decimal.charAt(1) + "分";
String zeroCent = decimal.charAt(1) + "";
if (zeroCent.equals("零")) {
rmb = integer + decimal.charAt(0) + "角";
} else {
rmb = integer + decimal.charAt(0) + "角" + decimal.charAt(1) + "分";
}
} else {
rmb = rmb + "元整";
}

return rmb;
}
}