最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java數(shù)字轉(zhuǎn)中文大寫工具類詳細(xì)代碼(拿去即用)

 更新時(shí)間:2024年05月20日 09:44:11   作者:UnIQUE?Eason  
最近項(xiàng)目中用到金額轉(zhuǎn)大寫的地方,索性給大家總結(jié)下,這篇文章主要給大家介紹了關(guān)于Java數(shù)字轉(zhuǎn)中文大寫工具類的相關(guān)資料,文中給出了詳細(xì)的代碼示例,需要的朋友可以參考下

工具類包括:

  • 數(shù)字轉(zhuǎn)中文大寫形式,比如一百二十一
  • 數(shù)字轉(zhuǎn)金額用的大寫形式,比如:壹佰貳拾壹
  • 轉(zhuǎn)金額形式,比如:壹佰貳拾壹整
package cn.hutool.core.convert;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;

/**
 * 數(shù)字轉(zhuǎn)中文類
 **/
public class NumberChineseFormatterUtils {

	/**
	 * 中文形式,奇數(shù)位置是簡(jiǎn)體,偶數(shù)位置是記賬繁體,0共用
	 * 使用混合數(shù)組提高效率和數(shù)組復(fù)用
	 **/
	private static final char[] DIGITS = {'零', '一', '壹', '二', '貳', '三', '叁', '四', '肆', '五', '伍',
			'六', '陸', '七', '柒', '八', '捌', '九', '玖'};

	/**
	 * 漢字轉(zhuǎn)阿拉伯?dāng)?shù)字的
	 */
	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('萬(wàn)', 1_0000, true),
			new ChineseUnit('億', 1_0000_0000, true),
	};


	/**
	 * 阿拉伯?dāng)?shù)字轉(zhuǎn)換成中文,小數(shù)點(diǎn)后四舍五入保留兩位. 使用于整數(shù)、小數(shù)的轉(zhuǎn)換.
	 *
	 * @param amount           數(shù)字
	 * @param isUseTraditional 是否使用繁體
	 * @return 中文
	 */
	public static String format(double amount, boolean isUseTraditional) {
		return format(amount, isUseTraditional, false);
	}

	/**
	 * 阿拉伯?dāng)?shù)字轉(zhuǎn)換成中文,小數(shù)點(diǎn)后四舍五入保留兩位. 使用于整數(shù)、小數(shù)的轉(zhuǎn)換.
	 *
	 * @param amount           數(shù)字
	 * @param isUseTraditional 是否使用繁體
	 * @param isMoneyMode      是否為金額模式
	 * @return 中文
	 */
	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)!");
		}

		// 負(fù)數(shù)
		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));
		//負(fù)數(shù)
		if (negative) { // 整數(shù)部分不為 0
			chineseStr.insert(0, "負(fù)");
		}

		// 小數(shù)部分
		if (numFen != 0 || numJiao != 0) {
			if (numFen == 0) {
				chineseStr.append(isMoneyMode ? "元" : "點(diǎn)").append(numberToChinese(numJiao, isUseTraditional)).append(isMoneyMode ? "角" : "");
			} else { // “分”數(shù)不為 0
				if (numJiao == 0) {
					chineseStr.append(isMoneyMode ? "元零" : "點(diǎn)零").append(numberToChinese(numFen, isUseTraditional)).append(isMoneyMode ? "分" : "");
				} else {
					chineseStr.append(isMoneyMode ? "元" : "點(diǎn)").append(numberToChinese(numJiao, isUseTraditional)).append(isMoneyMode ? "角" : "").append(numberToChinese(numFen, isUseTraditional)).append(isMoneyMode ? "分" : "");
				}
			}
		} else if (isMoneyMode) {
			//無(wú)小數(shù)部分的金額結(jié)尾
			chineseStr.append("元整");
		}

		return chineseStr.toString();
	}

	/**
	 * 數(shù)字字符轉(zhuǎn)中文,非數(shù)字字符原樣返回
	 *
	 * @param c                數(shù)字字符
	 * @param isUseTraditional 是否繁體
	 * @return 中文字符
	 * @since 5.3.9
	 */
	public static String numberCharToChinese(char c, boolean isUseTraditional) {
		if (c < '0' || c > '9') {
			return String.valueOf(c);
		}
		return String.valueOf(numberToChinese(c - '0', isUseTraditional));
	}

	/**
	 * 阿拉伯?dāng)?shù)字整數(shù)部分轉(zhuǎn)換成中文,只支持正數(shù)
	 *
	 * @param amount           數(shù)字
	 * @param isUseTraditional 是否使用繁體
	 * @return 中文
	 */
	private static String longToChinese(long amount, boolean isUseTraditional) {
		if(0 == amount){
			return "零";
		}

		//將數(shù)字以萬(wàn)為單位分為多份
		int[] parts = new int[4];
		for (int i = 0; amount != 0; i++) {
			parts[i] = (int) (amount % 10000);
			amount = amount / 10000;
		}

		final StringBuilder chineseStr = new StringBuilder();
		int partValue;
		String partChinese;

		// 千
		partValue = parts[0];
		if(partValue > 0){
			partChinese = thousandToChinese(partValue, isUseTraditional);
			chineseStr.insert(0, partChinese);

			if(partValue < 1000){
				// 和萬(wàn)位之間空0,則補(bǔ)零,如一萬(wàn)零三百
				addPreZero(chineseStr);
			}
		}

		// 萬(wàn)
		partValue = parts[1];
		if(partValue > 0){
			if((partValue % 10 == 0 && parts[0] > 0)){
				// 如果"萬(wàn)"的個(gè)位是0,則補(bǔ)零,如十萬(wàn)零八千
				addPreZero(chineseStr);
			}
			partChinese = thousandToChinese(partValue, isUseTraditional);
			chineseStr.insert(0, partChinese + "萬(wàn)");

			if(partValue < 1000){
				// 和億位之間空0,則補(bǔ)零,如一億零三百萬(wàn)
				addPreZero(chineseStr);
			}
		} else{
			addPreZero(chineseStr);
		}

		// 億
		partValue = parts[2];
		if(partValue > 0){
			if((partValue % 10 == 0 && parts[1] > 0)){
				// 如果"萬(wàn)"的個(gè)位是0,則補(bǔ)零,如十萬(wàn)零八千
				addPreZero(chineseStr);
			}

			partChinese = thousandToChinese(partValue, isUseTraditional);
			chineseStr.insert(0, partChinese + "億");

			if(partValue < 1000){
				// 和萬(wàn)億位之間空0,則補(bǔ)零,如一萬(wàn)億零三百億
				addPreZero(chineseStr);
			}
		} else{
			addPreZero(chineseStr);
		}

		// 萬(wàn)億
		partValue = parts[3];
		if(partValue > 0){
			if(parts[2] == 0){
				chineseStr.insert(0, "億");
			}
			partChinese = thousandToChinese(partValue, isUseTraditional);
			chineseStr.insert(0, partChinese + "萬(wàn)");
		}

		if(StrUtil.isNotEmpty(chineseStr) && '零' == chineseStr.charAt(0)){
			return chineseStr.substring(1);
		}

		return chineseStr.toString();
	}

	/**
	 * 把一個(gè) 0~9999 之間的整數(shù)轉(zhuǎn)換為漢字的字符串,如果是 0 則返回 ""
	 *
	 * @param amountPart       數(shù)字部分
	 * @param isUseTraditional 是否使用繁體單位
	 * @return 轉(zhuǎn)換后的漢字
	 */
	private static String thousandToChinese(int amountPart, boolean isUseTraditional) {
		int temp = amountPart;

		StringBuilder chineseStr = new StringBuilder();
		boolean lastIsZero = true; // 在從低位往高位循環(huán)時(shí),記錄上一位數(shù)字是不是 0
		for (int i = 0; temp > 0; i++) {
			int digit = temp % 10;
			if (digit == 0) { // 取到的數(shù)字為 0
				if (false == lastIsZero) {
					// 前一個(gè)數(shù)字不是 0,則在當(dāng)前漢字串前加“零”字;
					chineseStr.insert(0, "零");
				}
				lastIsZero = true;
			} else { // 取到的數(shù)字不是 0
				chineseStr.insert(0, numberToChinese(digit, isUseTraditional) + getUnitName(i, isUseTraditional));
				lastIsZero = false;
			}
			temp = temp / 10;
		}
		return chineseStr.toString();
	}

	/**
	 * 把中文轉(zhuǎn)換為數(shù)字 如 二百二十 220
	 * 
	 *  一百一十二 -》 112
	 *  一千零一十二 -》 1012
	 *
	 * @param chinese 中文字符
	 * @return 數(shù)字
	 */
	public static int chineseToNumber(String chinese) {
		final int length = chinese.length();
		int result = 0;

		// 節(jié)總和
		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) {
					// 遇到零時(shí)節(jié)結(jié)束,權(quán)位失效,比如兩萬(wàn)二零一十
					if (number > 0 && null != unit) {
						section += number * (unit.value / 10);
					}
					unit = null;
				} else if (number > 0) {
					// 多個(gè)數(shù)字同時(shí)出現(xiàn),報(bào)錯(cuò)
					throw new IllegalArgumentException(StrUtil.format("Bad number '{}{}' at: {}", chinese.charAt(i - 1), c, i));
				}
				// 普通數(shù)字
				number = num;
			} else {
				unit = chineseToUnit(c);
				if (null == unit) {
					// 出現(xiàn)非法字符
					throw new IllegalArgumentException(StrUtil.format("Unknown unit '{}' at: {}", c, i));
				}

				//單位
				if (unit.secUnit) {
					// 節(jié)單位,按照節(jié)求和
					section = (section + number) * unit.value;
					result += section;
					section = 0;
				} else {
					// 非節(jié)單位,和單位前的單數(shù)字組合為值
					int unitNumber = number;
					if(0 == number && 0 == i){
						// issue#1726,對(duì)于單位開頭的數(shù)組,默認(rèn)賦予1
						// 十二 -> 一十二
						// 百二 -> 一百二
						unitNumber = 1;
					}
					section += (unitNumber * unit.value);
				}
				number = 0;
			}
		}

		if (number > 0 && null != unit) {
			number = number * (unit.value / 10);
		}

		return result + section + number;
	}

	/**
	 * 查找對(duì)應(yīng)的權(quán)對(duì)象
	 *
	 * @param chinese 中文權(quán)位名
	 * @return 權(quán)對(duì)象
	 */
	private static ChineseUnit chineseToUnit(char chinese) {
		for (ChineseUnit chineseNameValue : CHINESE_NAME_VALUE) {
			if (chineseNameValue.name == chinese) {
				return chineseNameValue;
			}
		}
		return null;
	}

	/**
	 * 將漢字單個(gè)數(shù)字轉(zhuǎn)換為int類型數(shù)字
	 *
	 * @param chinese 漢字?jǐn)?shù)字,支持簡(jiǎn)體和繁體
	 * @return 數(shù)字,-1表示未找到
	 */
	private static int chineseToNumber(char chinese) {
		if ('兩' == chinese) {
			// 口語(yǔ)糾正
			chinese = '二';
		}
		final int i = ArrayUtil.indexOf(DIGITS, chinese);
		if (i > 0) {
			return (i + 1) / 2;
		}
		return i;
	}

	/**
	 * 單個(gè)數(shù)字轉(zhuǎn)漢字
	 *
	 * @param number           數(shù)字
	 * @param isUseTraditional 是否使用繁體
	 * @return 漢字
	 */
	private static char numberToChinese(int number, boolean isUseTraditional) {
		if (0 == number) {
			return DIGITS[0];
		}
		return DIGITS[number * 2 - (isUseTraditional ? 0 : 1)];
	}

	/**
	 * 獲取對(duì)應(yīng)級(jí)別的單位
	 *
	 * @param index            級(jí)別,0表示各位,1表示十位,2表示百位,以此類推
	 * @param isUseTraditional 是否使用繁體
	 * @return 單位
	 */
	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);
	}

	/**
	 * 權(quán)位
	 */
	private static class ChineseUnit {
		/**
		 * 中文權(quán)名稱
		 */
		private final char name;
		/**
		 * 10的倍數(shù)值
		 */
		private final int value;
		/**
		 * 是否為節(jié)權(quán)位,它不是與之相鄰的數(shù)字的倍數(shù),而是整個(gè)小節(jié)的倍數(shù)。

		 * 例如二十三萬(wàn),萬(wàn)是節(jié)權(quán)位,與三無(wú)關(guān),而和二十三關(guān)聯(lián)
		 */
		private final boolean secUnit;

		/**
		 * 構(gòu)造
		 *
		 * @param name    名稱
		 * @param value   值,即10的倍數(shù)
		 * @param secUnit 是否為節(jié)權(quán)位
		 */
		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, '零');
		}
	}
}

注意:以上代碼用到hutool工具,需要引入依賴:

		<dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.5</version>
        </dependency>

附:數(shù)字轉(zhuǎn)換

// 數(shù)字轉(zhuǎn)英文
double a = 23.56;
// TWENTY THREE AND CENTS FIFTY SIX ONLY
String a1 = Convert.numberToWord(a);
 
// 數(shù)字轉(zhuǎn)中文
long b = 345673;
// 跟Convert.digitToChinese方法一樣,第二個(gè)參數(shù)如果設(shè)為false,就是中文的一二三四...
String s = Convert.numberToChinese(b, true);
 
// 數(shù)字簡(jiǎn)化
long b = 345673;
// 34.57w
String s = Convert.numberToSimple(b);
log.info(s);
// 1.2k
String s1 = Convert.numberToSimple(1200);
log.info(s1);
 
// 中文數(shù)字轉(zhuǎn)數(shù)字
// 1012
int b = Convert.chineseToNumber("一千零一十二");
log.info(b + "");

總結(jié) 

到此這篇關(guān)于Java數(shù)字轉(zhuǎn)中文大寫工具類的文章就介紹到這了,更多相關(guān)Java數(shù)字轉(zhuǎn)中文大寫工具類內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Nacos與SpringBoot實(shí)現(xiàn)配置管理的開發(fā)實(shí)踐

    Nacos與SpringBoot實(shí)現(xiàn)配置管理的開發(fā)實(shí)踐

    在微服務(wù)架構(gòu)中,配置管理是一個(gè)核心組件,而Nacos為此提供了一個(gè)強(qiáng)大的解決方案,本文主要介紹了Nacos與SpringBoot實(shí)現(xiàn)配置管理的開發(fā)實(shí)踐,具有一定的參考價(jià)值
    2023-08-08
  • SpringBoot整合MinIO實(shí)現(xiàn)文件上傳的方法詳解

    SpringBoot整合MinIO實(shí)現(xiàn)文件上傳的方法詳解

    一般涉及到文件上傳,基本上都是保存在項(xiàng)目本地,這種方式比較省事,但是安全性不高。所以今天給大伙詳細(xì)介紹一些如何利用MinIO實(shí)現(xiàn)文件上傳,感興趣的可以了解一下
    2022-05-05
  • arthas?jprofiler做復(fù)雜鏈路的調(diào)用分析

    arthas?jprofiler做復(fù)雜鏈路的調(diào)用分析

    這篇文章主要為大家介紹了arthas?jprofiler做復(fù)雜鏈路的調(diào)用分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • java單例模式學(xué)習(xí)示例

    java單例模式學(xué)習(xí)示例

    java中單例模式是一種常見的設(shè)計(jì)模式,單例模式分三種:懶漢式單例、餓漢式單例、登記式單例三種,下面提供了單例模式的示例
    2014-01-01
  • SpringBoot使用Thymeleaf自定義標(biāo)簽的實(shí)例代碼

    SpringBoot使用Thymeleaf自定義標(biāo)簽的實(shí)例代碼

    這篇文章主要介紹了SpringBoot使用Thymeleaf自定義標(biāo)簽的實(shí)例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-09-09
  • Spring Boot整合SSE實(shí)時(shí)通信的問(wèn)題小結(jié)

    Spring Boot整合SSE實(shí)時(shí)通信的問(wèn)題小結(jié)

    本文介紹了服務(wù)器發(fā)送事件(Server-Sent Events,SSE)技術(shù),其主要特點(diǎn)包括單向數(shù)據(jù)流、自動(dòng)重連、自定義事件類型等,SSE適用于實(shí)時(shí)更新場(chǎng)景,如新聞推送、評(píng)論系統(tǒng)等,感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • 詳解springboot解決CORS跨域的三種方式

    詳解springboot解決CORS跨域的三種方式

    本文主要介紹了詳解springboot解決CORS跨域的三種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • JAVA中String介紹及常見面試題小結(jié)

    JAVA中String介紹及常見面試題小結(jié)

    這篇文章主要介紹了JAVA中String介紹及常見面試題,在java面試中經(jīng)常會(huì)被面試官問(wèn)到,小編通過(guò)實(shí)例代碼相結(jié)合給大家詳細(xì)介紹,需要的朋友可以參考下
    2020-02-02
  • Java源碼解析之HashMap的put、resize方法詳解

    Java源碼解析之HashMap的put、resize方法詳解

    這篇文章主要介紹了Java源碼解析之HashMap的put、resize方法詳解,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有很大的幫助,需要的朋友可以參考下
    2021-04-04
  • 在SpringBoot接口中正確地序列化時(shí)間字段的方法

    在SpringBoot接口中正確地序列化時(shí)間字段的方法

    文章主要介紹在 Spring Boot 接口中正確序列化時(shí)間字段的方法,包括 Java 中Date和LocalDateTime類型的區(qū)別,JSON 序列化和請(qǐng)求參數(shù)中時(shí)間字段的處理,如時(shí)間字符串的格式配置、時(shí)間戳的使用及相關(guān)配置,還提到了在 Swagger UI 中的類型設(shè)置,需要的朋友可以參考下
    2024-11-11

最新評(píng)論

鹤山市| 华宁县| 隆子县| 和林格尔县| 铁岭市| 洛浦县| 乌鲁木齐市| 商南县| 姚安县| 扶绥县| 贵港市| 边坝县| 嘉黎县| 迁西县| 民乐县| 射洪县| 富顺县| 咸宁市| 无棣县| 漠河县| 镇巴县| 北碚区| 闽清县| 读书| 合水县| 绿春县| 原阳县| 灵丘县| 镇雄县| 文水县| 探索| 黄冈市| 专栏| 惠水县| 浦江县| 阿勒泰市| 鹤峰县| 嘉义市| 阜新市| 安龙县| 红桥区|