金錢數字轉換成中文數值
阿新 • • 發佈:2021-01-31
技術標籤:FrameTool金錢數字轉換成中文數值
金錢數字轉換成中文數值
關於中文數值表示參考連結:https://baike.baidu.com/item/%E4%B8%AD%E6%96%87%E6%95%B0%E5%AD%97/2921705?fr=aladdin
package top.simba1949;
import java.util.*;
/**
* 最高支援:1京 減 0.01
*
* 設計思路:
* 將字串通過小數點分割為整數部分和小數部分(小數部分取2位)
*
* 整數部分處理思路:
* 數字字串從後往前數,每8位一個單元,千百十萬千百十個+單位
* 每個單元,第三位是萬位,需要特殊處理,
* |->如果萬前面存在數字,但是萬位沒有數值,需要新增上萬,
* |->如果萬前面沒有數值同時萬沒有數值,不用新增
*
* 小數部分處理思路:
* 判斷是否是否存在
* |->存在,先取第一位小數位做角,然後判斷長度是否大於2,
* | |->不大於2,直接返回
* | |->大於2再取第二位小數做分返回
* |->不存在,返回`整`
* @author anthony
* @date 2021/1/26
*/
public class MoneyUtils {
private static final String NUMBER_ZERO_STR = "0";
private static final String NUMBER_ONE_STR = "1";
private static final String NUMBER_TWO_STR = "2";
private static final String NUMBER_THREE_STR = "3";
private static final String NUMBER_FOUR_STR = "4";
private static final String NUMBER_FIVE_STR = "5";
private static final String NUMBER_SIX_STR = "6";
private static final String NUMBER_SEVEN_STR = "7";
private static final String NUMBER_EIGHT_STR = "8" ;
private static final String NUMBER_NINE_STR = "9";
private static final String NUMBER_POINT_STR = ".";
private static final String DELIMITER_DECIMAL_POINT = "\\.";
private static final String DELIMITER_COMMA = ",";
private static final String CN_NUMBER_ZERO_STR = "零";
private static final String CN_NUMBER_ONE_STR = "壹";
private static final String CN_NUMBER_TWO_STR = "貳";
private static final String CN_NUMBER_THREE_STR = "叄";
private static final String CN_NUMBER_FOUR_STR = "肆";
private static final String CN_NUMBER_FIVE_STR = "伍";
private static final String CN_NUMBER_SIX_STR = "陸";
private static final String CN_NUMBER_SEVEN_STR = "柒";
private static final String CN_NUMBER_EIGHT_STR = "捌";
private static final String CN_NUMBER_NINE_STR = "玖";
private static final String CN_NUMBER_TEN_STR = "拾";
private static final String CN_NUMBER_HUNDRED_STR = "佰";
private static final String CN_NUMBER_THOUSAND_STR = "仟";
private static final String CN_NUMBER_TEN_THOUSAND_STR = "萬";
private static final String CN_NUMBER_BILLION_STR = "億";
private static final String CN_NUMBER_TRILLION_STR = "兆";
private static final String RMB_UNIT_YUAN = "圓";
private static final String RMB_UNIT_JIAO = "角";
private static final String RMB_UNIT_FEN = "分";
private static final String NO_POINT = "整";
/**
* 數值與中文數字對映關係
*/
private static Map<String, String> numberMap = new HashMap<>(16);
/**
* 長度與單位對映關係
*/
private static Map<Integer, String> unitMap = new HashMap<>(16);
/**
* 從後往前數,每8個為單位,獲取單位數值,千,百,十,萬,千,百,十,一
*/
private static Map<Integer, String> unitMap4Digits = new HashMap<>(16);
static {
numberMap.put(NUMBER_ZERO_STR, CN_NUMBER_ZERO_STR);
numberMap.put(NUMBER_ONE_STR, CN_NUMBER_ONE_STR);
numberMap.put(NUMBER_TWO_STR, CN_NUMBER_TWO_STR);
numberMap.put(NUMBER_THREE_STR, CN_NUMBER_THREE_STR);
numberMap.put(NUMBER_FOUR_STR, CN_NUMBER_FOUR_STR);
numberMap.put(NUMBER_FIVE_STR, CN_NUMBER_FIVE_STR);
numberMap.put(NUMBER_SIX_STR, CN_NUMBER_SIX_STR);
numberMap.put(NUMBER_SEVEN_STR, CN_NUMBER_SEVEN_STR);
numberMap.put(NUMBER_EIGHT_STR, CN_NUMBER_EIGHT_STR);
numberMap.put(NUMBER_NINE_STR, CN_NUMBER_NINE_STR);
}
static {
unitMap4Digits.put(1, "");
unitMap4Digits.put(2, CN_NUMBER_TEN_STR);
unitMap4Digits.put(3, CN_NUMBER_HUNDRED_STR);
unitMap4Digits.put(4, CN_NUMBER_THOUSAND_STR);
unitMap4Digits.put(5, CN_NUMBER_TEN_THOUSAND_STR);
unitMap4Digits.put(6, CN_NUMBER_TEN_STR);
unitMap4Digits.put(7, CN_NUMBER_HUNDRED_STR);
unitMap4Digits.put(8, CN_NUMBER_THOUSAND_STR);
}
static {
// 圓
unitMap.put(1, RMB_UNIT_YUAN);
// 億
unitMap.put(2, CN_NUMBER_BILLION_STR);
// 兆
unitMap.put(3, CN_NUMBER_TRILLION_STR);
}
/**
* 錢幣
* 數字轉換成中文大寫
* 目前最大支援一兆
* @return
*/
public static String moneyNumber2CnNumber(String original){
if (null == original || original.trim().isEmpty()){
return "";
}
// beforePoint 表示整數部分,afterPoint表示小數部分
String beforePoint, afterPoint= "";
String originalTrim = original.replace(" ", "").trim();
if (originalTrim.contains(NUMBER_POINT_STR)){
// 存在小數點
String[] split = originalTrim.split(DELIMITER_DECIMAL_POINT);
beforePoint = split[0].trim();
afterPoint = split[1].trim();
}else {
// 不存在小數點
beforePoint = originalTrim;
}
return integerDealWith(beforePoint) + decimalDealWith(afterPoint);
}
/**
* 整數部分處理方式
* @param integer
* @return
*/
private static String integerDealWith(String integer){
if (null == integer || integer.trim().isEmpty()){
return "";
}
// 從後往前數,每8位新增一個分割符號,
List<String> list = new ArrayList<>();
char[] chars = integer.trim().toCharArray();
int j = 1;
for (int i = chars.length - 1; i >= 0; i--) {
list.add(String.valueOf(chars[i]));
if (j%8 == 0){
list.add(DELIMITER_COMMA);
}
j++;
}
Collections.reverse(list);
// 獲取帶有分割符`,`的字串
StringBuilder builder = new StringBuilder();
list.forEach(builder::append);
String str = builder.toString();
// 去掉頭部逗號
if (str.startsWith(DELIMITER_COMMA)){
str = str.replaceFirst(DELIMITER_COMMA, "");
}
// 每8位分割後處理
StringBuilder resultBuilder = new StringBuilder();
String[] split = str.split(DELIMITER_COMMA);
int length = split.length;
for (int i = 0; i < length; i++) {
resultBuilder.append(integerDealWithCoreWithUnit(split[i], unitMap.get(length - i)));
}
return resultBuilder.toString();
}
/**
* 數字按照 `千萬百萬十萬,萬千百十個` 排序
* @param number
* @param unit 最後的單位
* @return
*/
private static String integerDealWithCoreWithUnit(String number, String unit){
if (null == number || number.trim().isEmpty() || null == unit){
return "";
}
StringBuilder builder = new StringBuilder();
int length = number.length();
int j = length;
for (int i = 0; i < length; i++) {
String value = String.valueOf(number.charAt(i));
if (!NUMBER_ZERO_STR.equals(value)){
builder.append(numberMap.get(value)).append(unitMap4Digits.get(j));
}else {
// 8位數,第四位數沒有值但是前面有值
if (i == 3 && builder.length() > 0){
builder.append(CN_NUMBER_TEN_THOUSAND_STR);
}
}
j--;
}
// 新增最後的單位
if (builder.length() > 0){
builder.append(unit);
}
return builder.toString();
}
/**
* 小數部分處理方式
* @param decimal
* @return
*/
private static String decimalDealWith(String decimal){
if (null == decimal || decimal.trim().isEmpty()){
return NO_POINT;
}
// 自取兩位小數
StringBuilder builder = new StringBuilder();
// 角
String decimalTrim = decimal.trim();
String tenthsNumberStr = String.valueOf(decimalTrim.charAt(0));
if (!NUMBER_ZERO_STR.equals(tenthsNumberStr)){
builder.append(numberMap.get(tenthsNumberStr)).append(RMB_UNIT_JIAO);
}
// 分
if (decimalTrim.length() >= 2){
String percentileNumberStr = String.valueOf(decimalTrim.charAt(1));
if (!NUMBER_ZERO_STR.equals(percentileNumberStr)){
builder.append(numberMap.get(percentileNumberStr)).append(RMB_UNIT_FEN);
}
}
return builder.toString();
}
private MoneyUtils() {
}
}