数字转中文工具类
package com.lym.util;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
public class NumberChineseFormatterUtils {
private static final char[] DIGITS = {'零', '一', '壹', '二', '贰', '三', '叁', '四', '肆', '五', '伍',
'六', '陆', '七', '柒', '八', '捌', '九', '玖'};
private static final ChineseUnit[] CHINESE_NAME_VALUE = {
new ChineseUnit(' ', 1, false),
new ChineseUnit('十', 10, false),
new ChineseUnit('拾', 10, false),
new ChineseUnit('百', 100, false),
new ChineseUnit('佰', 100, false),
new ChineseUnit('千', 1000, false),
new ChineseUnit('仟', 1000, false),
new ChineseUnit('万', 1_0000, true),
new ChineseUnit('亿', 1_0000_0000, true),
};
public static String format(double amount, boolean isUseTraditional) {
return format(amount, isUseTraditional, false);
}
public static String format(double amount, boolean isUseTraditional, boolean isMoneyMode) {
if (amount > 99_9999_9999_9999.99 || amount < -99999999999999.99) {
throw new IllegalArgumentException("Number support only: (-99999999999999.99 ~ 99999999999999.99)!");
}
boolean negative = false;
if (amount < 0) {
negative = true;
amount = -amount;
}
long temp = Math.round(amount * 100);
final int numFen = (int) (temp % 10);
temp = temp / 10;
final int numJiao = (int) (temp % 10);
temp = temp / 10;
final StringBuilder chineseStr = new StringBuilder(longToChinese(temp, isUseTraditional));
if (negative) {
chineseStr.insert(0, "负");
}
if (numFen != 0 || numJiao != 0) {
if (numFen == 0) {
chineseStr.append(isMoneyMode ? "元" : "点").append(numberToChinese(numJiao, isUseTraditional)).append(isMoneyMode ? "角" : "");
} else {
if (numJiao == 0) {
chineseStr.append(isMoneyMode ? "元零" : "点零").append(numberToChinese(numFen, isUseTraditional)).append(isMoneyMode ? "分" : "");
} else {
chineseStr.append(isMoneyMode ? "元" : "点").append(numberToChinese(numJiao, isUseTraditional)).append(isMoneyMode ? "角" : "").append(numberToChinese(numFen, isUseTraditional)).append(isMoneyMode ? "分" : "");
}
}
} else if (isMoneyMode) {
chineseStr.append("元整");
}
return chineseStr.toString();
}
public static String numberCharToChinese(char c, boolean isUseTraditional) {
if (c < '0' || c > '9') {
return String.valueOf(c);
}
return String.valueOf(numberToChinese(c - '0', isUseTraditional));
}
public static String longToChinese(long amount, boolean isUseTraditional) {
if(0 == amount){
return "零";
}
int[] parts = new int[4];
int max = 0;
for (int i = 0; amount != 0; i++) {
parts[i] = (int) (amount % 10000);
amount = amount / 10000;
max = i;
}
final StringBuilder chineseStr = new StringBuilder();
int partValue;
String partChinese;
partValue = parts[0];
if(partValue > 0){
partChinese = thousandToChinese(partValue, isUseTraditional, max==0);
chineseStr.insert(0, partChinese);
if(partValue < 1000){
addPreZero(chineseStr);
}
}
partValue = parts[1];
if(partValue > 0){
if((partValue % 10 == 0 && parts[0] > 0)){
addPreZero(chineseStr);
}
partChinese = thousandToChinese(partValue, isUseTraditional,max==1);
chineseStr.insert(0, partChinese + "万");
if(partValue < 1000){
addPreZero(chineseStr);
}
} else{
addPreZero(chineseStr);
}
partValue = parts[2];
if(partValue > 0){
if((partValue % 10 == 0 && parts[1] > 0)){
addPreZero(chineseStr);
}
partChinese = thousandToChinese(partValue, isUseTraditional,max==2);
chineseStr.insert(0, partChinese + "亿");
if(partValue < 1000){
addPreZero(chineseStr);
}
} else{
addPreZero(chineseStr);
}
partValue = parts[3];
if(partValue > 0){
if(parts[2] == 0){
chineseStr.insert(0, "亿");
}
partChinese = thousandToChinese(partValue, isUseTraditional,max==3);
chineseStr.insert(0, partChinese + "万");
}
if(StrUtil.isNotEmpty(chineseStr) && '零' == chineseStr.charAt(0)){
return chineseStr.substring(1);
}
return chineseStr.toString();
}
private static String thousandToChinese(int amountPart, boolean isUseTraditional, boolean isMax) {
int temp = amountPart;
StringBuilder chineseStr = new StringBuilder();
if(isMax){
if( temp / 10 == 1){
if (temp % 10 != 0){
chineseStr.insert(0,numberToChinese(temp % 10, isUseTraditional) + getUnitName(0, isUseTraditional));
}
chineseStr.insert(0,getUnitName(temp / 10, isUseTraditional));
return chineseStr.toString();
}
}
boolean lastIsZero = true;
for (int i = 0; temp > 0; i++) {
int digit = temp % 10;
if (digit == 0) {
if (false == lastIsZero) {
chineseStr.insert(0, "零");
}
lastIsZero = true;
} else {
chineseStr.insert(0, numberToChinese(digit, isUseTraditional) + getUnitName(i, isUseTraditional));
lastIsZero = false;
}
temp = temp / 10;
}
return chineseStr.toString();
}
public static int chineseToNumber(String chinese) {
final int length = chinese.length();
int result = 0;
int section = 0;
int number = 0;
ChineseUnit unit = null;
char c;
for (int i = 0; i < length; i++) {
c = chinese.charAt(i);
final int num = chineseToNumber(c);
if (num >= 0) {
if (num == 0) {
if (number > 0 && null != unit) {
section += number * (unit.value / 10);
}
unit = null;
} else if (number > 0) {
throw new IllegalArgumentException(StrUtil.format("Bad number '{}{}' at: {}", chinese.charAt(i - 1), c, i));
}
number = num;
} else {
unit = chineseToUnit(c);
if (null == unit) {
throw new IllegalArgumentException(StrUtil.format("Unknown unit '{}' at: {}", c, i));
}
if (unit.secUnit) {
section = (section + number) * unit.value;
result += section;
section = 0;
} else {
int unitNumber = number;
if(0 == number && 0 == i){
unitNumber = 1;
}
section += (unitNumber * unit.value);
}
number = 0;
}
}
if (number > 0 && null != unit) {
number = number * (unit.value / 10);
}
return result + section + number;
}
private static ChineseUnit chineseToUnit(char chinese) {
for (ChineseUnit chineseNameValue : CHINESE_NAME_VALUE) {
if (chineseNameValue.name == chinese) {
return chineseNameValue;
}
}
return null;
}
private static int chineseToNumber(char chinese) {
if ('两' == chinese) {
chinese = '二';
}
final int i = ArrayUtil.indexOf(DIGITS, chinese);
if (i > 0) {
return (i + 1) / 2;
}
return i;
}
private static char numberToChinese(int number, boolean isUseTraditional) {
if (0 == number) {
return DIGITS[0];
}
return DIGITS[number * 2 - (isUseTraditional ? 0 : 1)];
}
private static String getUnitName(int index, boolean isUseTraditional) {
if (0 == index) {
return StrUtil.EMPTY;
}
return String.valueOf(CHINESE_NAME_VALUE[index * 2 - (isUseTraditional ? 0 : 1)].name);
}
private static class ChineseUnit {
private final char name;
private final int value;
private final boolean secUnit;
public ChineseUnit(char name, int value, boolean secUnit) {
this.name = name;
this.value = value;
this.secUnit = secUnit;
}
}
private static void addPreZero(StringBuilder chineseStr){
if(StrUtil.isEmpty(chineseStr)){
return;
}
final char c = chineseStr.charAt(0);
if('零' != c){
chineseStr.insert(0, '零');
}
}
public static void main(String[] args) {
String str = "110";
System.out.println(longToChinese(Long.parseLong(str), false));
}
}