1. 程式人生 > >人民幣大小寫轉換 java 實現

人民幣大小寫轉換 java 實現

參考:http://blog.csdn.net/guaishushu1ss/article/details/76757405

對匹配的金額大小,轉換規則做了部分修改

工具類:

public class CurrencyUtil {
	/**
	 * 轉換為中國人民幣大寫字串,精確到分
	 * @param money 傳入小寫數字字串
	 * @return
	 * @throws Exception
	 */
	public static String toChinaUpper(String money) throws Exception {
		boolean lessZero = false;
		if(money.startsWith("-")) {
			money = money.substring(1);
			lessZero = true;
		}
		
		if (!money.matches("^[0-9]*$|^0+\\.[0-9]+$|^[1-9]+[0-9]*$|^[1-9]+[0-9]*.[0-9]+$")) {
			throw new Exception("錢數格式錯誤!");
		}
		String[] part = money.split("\\.");
		String integerData = part[0];
		String decimalData = part.length > 1 ? part[1] : "";
		//替換前置0
		if(integerData.matches("^0+$"))
		{
			integerData = "0";
		}else if(integerData.matches("^0+(\\d+)$")){
			integerData = integerData.replaceAll("^0+(\\d+)$", "$1");
		}		
		
		StringBuffer integer = new StringBuffer();
		for (int i = 0; i < integerData.length(); i++) {
			char perchar = integerData.charAt(i);
			integer.append(upperNumber(perchar));
			integer.append(upperNumber(integerData.length() - i - 1));
		}
		StringBuffer decimal = new StringBuffer();
		if (part.length > 1 && !"00".equals(decimalData)) {
			int length = decimalData.length() >= 2 ? 2 : decimalData.length();
			for (int i = 0; i < length; i++) {
				char perchar = decimalData.charAt(i);
				decimal.append(upperNumber(perchar));
				if (i == 0)
					decimal.append('角');
				if (i == 1)
					decimal.append('分');
			}
		}
		String result = integer.toString() + decimal.toString();
		result = dispose(result);
		if(lessZero && !"零圓整".equals(result)) {
			result = "負" + result;
		}
		return result;
	}

	private static char upperNumber(char number) {
		switch (number) {
		case '0':
			return '零';
		case '1':
			return '壹';
		case '2':
			return '貳';
		case '3':
			return '叄';
		case '4':
			return '肆';
		case '5':
			return '伍';
		case '6':
			return '陸';
		case '7':
			return '柒';
		case '8':
			return '捌';
		case '9':
			return '玖';
		}
		return '0';
	}

	private static char upperNumber(int index) {
		int realIndex =  index  % 9;
		if(index > 8) {//億過後進入迴歸,之後是拾,佰...
			realIndex =  (index - 9) % 8;
			realIndex = realIndex + 1;
		}
		switch (realIndex) {
		case 0:
			return '圓';
		case 1:
			return '拾';
		case 2:
			return '佰';
		case 3:
			return '仟';
		case 4:
			return '萬';
		case 5:
			return '拾';
		case 6:
			return '佰';
		case 7:
			return '仟';
		case 8:
			return '億';
		}
		return '0';
	}

	private static String dispose(String result) {
		result = result.replaceAll("0", "");//處理
		result = result.replaceAll("零仟零佰零拾|零仟零佰|零佰零拾|零仟|零佰|零拾", "零");
		result = result.replaceAll("零+", "零").replace("零億", "億");
		result = result.matches("^.*億零萬[^零]仟.*$") ? result.replace("零萬", "零") : result.replace("零萬", "萬");	
		result = result.replace("億萬", "億");
		//處理小數
		result = result.replace("零角", "零").replace("零分", "");	
		result = result.replaceAll("(^[零圓]*)(.+$)", "$2");	
		result = result.replaceAll("(^.*)([零]+圓)(.+$)", "$1圓零$3");
		
		//處理整數單位
		result = result.replaceAll("圓零角零分|圓零角$|圓$|^零$|圓零$|零圓$", "圓整");
		result = result.replaceAll("^圓整$", "零圓整");
		
		
		return result;
	}
}

測試類:
public class CurrencyUtilTest {
	@Test
    public void test(){
        try {
        	Assert.assertEquals(CurrencyUtil.toChinaUpper("0"),"零圓整");
        	Assert.assertEquals(CurrencyUtil.toChinaUpper("000000000000"),"零圓整");
        	Assert.assertEquals(CurrencyUtil.toChinaUpper("0.00"),"零圓整");
        	Assert.assertEquals(CurrencyUtil.toChinaUpper("0.03"),"叄分");
        	Assert.assertEquals(CurrencyUtil.toChinaUpper("0.43"),"肆角叄分");
        	Assert.assertEquals(CurrencyUtil.toChinaUpper("0000.43"),"肆角叄分");
        	Assert.assertEquals(CurrencyUtil.toChinaUpper("10000.43"),"壹萬圓零肆角叄分");
        	Assert.assertEquals(CurrencyUtil.toChinaUpper("000000000000.000"),"零圓整");
        	Assert.assertEquals(CurrencyUtil.toChinaUpper("421.0"),"肆佰貳拾壹圓整");
        	Assert.assertEquals(CurrencyUtil.toChinaUpper("421.0000"),"肆佰貳拾壹圓整");
        	Assert.assertEquals(CurrencyUtil.toChinaUpper("215224635421.00"),"貳仟壹佰伍拾貳億貳仟肆佰陸拾叄萬伍仟肆佰貳拾壹圓整");
        	Assert.assertEquals(CurrencyUtil.toChinaUpper("215224635421.53"),"貳仟壹佰伍拾貳億貳仟肆佰陸拾叄萬伍仟肆佰貳拾壹圓伍角叄分");
        	Assert.assertEquals(CurrencyUtil.toChinaUpper("215224635421.03"),     "貳仟壹佰伍拾貳億貳仟肆佰陸拾叄萬伍仟肆佰貳拾壹圓零叄分");
        	Assert.assertEquals(CurrencyUtil.toChinaUpper("2463215224635421.03"),"貳仟肆佰陸拾叄萬貳仟壹佰伍拾貳億貳仟肆佰陸拾叄萬伍仟肆佰貳拾壹圓零叄分");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("1"),"壹圓整");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("10"),"壹拾圓整");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("20.7"),"貳拾圓零柒角");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("10.70"),"壹拾圓零柒角");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("18.5"),"壹拾捌圓伍角");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("200.5"),"貳佰圓零伍角");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("2000"),"貳仟圓整");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("50000"),"伍萬圓整");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("500000"),"伍拾萬圓整");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("5000000"),"伍佰萬圓整");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("50000000"),"伍仟萬圓整");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("500000000"),"伍億圓整");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("5000000000"),"伍拾億圓整");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("5000000001"),"伍拾億零壹圓整");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("5000000021"),"伍拾億零貳拾壹圓整");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("5000000421"),"伍拾億零肆佰貳拾壹圓整");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("5000005421"),"伍拾億零伍仟肆佰貳拾壹圓整");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("5000035421"),"伍拾億零叄萬伍仟肆佰貳拾壹圓整");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("5000635421"),"伍拾億零陸拾叄萬伍仟肆佰貳拾壹圓整");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("5004635421"),"伍拾億零肆佰陸拾叄萬伍仟肆佰貳拾壹圓整");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("5024635421"),"伍拾億貳仟肆佰陸拾叄萬伍仟肆佰貳拾壹圓整");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("5224635421"),"伍拾貳億貳仟肆佰陸拾叄萬伍仟肆佰貳拾壹圓整");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("15224635421"),"壹佰伍拾貳億貳仟肆佰陸拾叄萬伍仟肆佰貳拾壹圓整");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("215224635421"),"貳仟壹佰伍拾貳億貳仟肆佰陸拾叄萬伍仟肆佰貳拾壹圓整");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("500021"),"伍拾萬零貳拾壹圓整");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("5000821"),"伍佰萬零捌佰貳拾壹圓整");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("5050006501"),"伍拾億伍仟萬陸仟伍佰零壹圓整");
            Assert.assertEquals(CurrencyUtil.toChinaUpper("550300001"),"伍億伍仟零叄拾萬零壹圓整");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


附上轉換的一些規則:

人民幣常識
人民幣金額中文大寫漢字主要包括:零、壹、貳、叄、肆、伍、陸、柒、捌、玖、拾、佰、仟、萬、億。
人民幣(縮寫為RMB)是我國大陸地區的法定貨幣,儘管每個人幾乎天天都要接觸到人民幣或者支票,但是人民幣大寫如何寫是困擾很多人的問題。
儘管生活中看起來極其熟悉而又簡單的東西,但發現其實並不會寫。人民幣在ISO 4217簡稱為CNY(China Yuan),常用簡寫為RMB(Ren Min Bi);人民幣貨幣的符號是“ ¥”('Y'+'='),讀音為“YUAN”。
人民幣按照材料的自然屬性劃分,有金屬幣(亦稱硬幣)、紙幣(亦稱鈔票)。無論紙幣、硬幣均等價流通,至今已發行了五套人民幣。
人民幣大寫規範介紹
銀行、單位和個人填寫的各種票據和結算憑證是辦理支付結算和現金收付的重要依據,直接關係到支付結算的準確、及時和安全。票據和結算憑證是銀行、單位和個人憑以記載賬務的會計憑證,是記載經濟業務和明確經濟責任的一種書面證明。因此,填寫票據和結算憑證必須做到標準化、規範化、要素齊全、數字正確、字跡清晰、不錯漏、不潦草、防止塗改。
中文大寫金額數字應用正楷或行書填寫,如壹、貳、叄、肆、伍、陸、柒、捌、玖、拾、佰、仟、萬、億、元、角、分、零、整(正)等字樣,不得用一、二(兩)、三、四、五、六、七、八、九、十、毛、另(或0)填寫,不得自造簡化字。如果金額數字書寫中使用繁體字,如貳、陸、億、萬、圓的,也應受理。 
人民幣大寫的正確寫法還應注意以下幾項:
一、中文大寫金額數字到“元”為止的,在“元”之後、應寫“整”(或“正”)字;在“角”之後,可以不寫“整”(或“正”)字;大寫金額數字有“分”的,“分”後面不寫“整”(或“正”)字。
二、中文大寫金額數字前應標明“人民幣”字樣,大寫金額數字應緊接“人民幣”字樣填寫,不得留有空白。大寫金額數字前未印“人民幣”字樣的,應加填“人民幣”三字,在票據和結算憑證大寫金額欄內不得預印固定的“仟、佰、拾、萬、仟、佰、拾、元、角、分”字樣。
三、阿拉伯數字小寫金額數字中有“0”時,中文大寫應按照漢語語言規律、金額數字構成和防止塗改的要求進行書寫。
四、阿拉伯小寫金額數字前面均應填寫人民幣符號“¥”,阿拉伯小寫金額數字要認真填寫,不得連寫分辨不清。
五、票據的出票日期必須使用中文大寫,為防止變造票據的出票日期,在填寫月、日時、月為壹、貳和壹拾的,日為壹至玖和壹拾、貳拾和叄拾的,應在其前加“零”,日為拾壹至拾玖的應在其前加“壹”,如1月15日應寫成零壹月壹拾伍日,再如10月20日應寫成零壹拾月零貳拾日。
六、票據出票日期使用小寫填寫的,銀行不予受理;大寫日期未按要求規範填寫的,銀行可予受理,但由此造成損失的由出票人自行承擔。