工具篇——MoneyFormatUtil(用于將人民幣小寫金額轉換成大寫金額)

代碼如下:

package com.wy.test.other;

/**

* 人民幣格式化工具

* 用于將人民幣小寫金額轉換成大寫金額

* 要點:1.區(qū)分金額是整數(shù)還是小數(shù)击敌,需要分開處理谓松;

*       2.將金額數(shù)字倒序,便于同單位合并

*       3.異常處理,判斷數(shù)字中是否含有非法字符盯腌,有則return溉知;

*       4.數(shù)字中0的處理;

*/

public class MoneyFormatUtil {

    //單位

    private static final char[] UNIT = {'億', '拾', '佰', '仟', '萬', '拾', '佰', '仟'};

    //大寫金額模板

    private static final char[] TEMPLATE = {'零', '壹', '貳', '叁', '肆', '伍', '陸', '柒', '捌', '玖'};

    private String submoneyCN[] = {"", "拾", "佰", "仟"};                                    //表示數(shù)字位數(shù)的數(shù)組

    private String numberCNN[] = {"零", "壹", "貳", "叁", "肆", "伍", "陸", "柒", "捌", "玖"};    //大寫數(shù)字的數(shù)組

    private static MoneyFormatUtil instance;

    /**

     * 獲取類的實例

     *

     * @return 類的實例

     */

    public static MoneyFormatUtil getInstance() {

        if (instance == null) {

            instance = new MoneyFormatUtil();

        }

        return instance;

    }

    /**

     * 將人民幣小寫金額轉換成大寫金額

     *

     * @return 轉換后的大寫金額

     */

    public String convert(String money) {

        String formatCN = "";

        int point = money.indexOf(".");                //判斷字符串是否包含小數(shù)點(不包含返回-1)

        if (point != -1) {//包含小數(shù)點的情況

            formatCN = decimalConversion(money, point);

        } else {

            formatCN = integerConversion(money);

        }

        return formatCN;

    }

    /**

     * 小數(shù)轉換

     *

     * @param decimalString 小數(shù)字符串(例:1234567.89  壹佰貳拾叁萬肆仟伍佰陸拾柒元捌角玖分)

     * @param pointPosition 小數(shù)點在字符串中的位置

     * @return 轉換后的大寫金額

     */

    private String decimalConversion(String decimalString, int pointPosition) {

        String formatDecimalString = "";

        String money1 = decimalString.substring(0, pointPosition);    //小數(shù)點之前的部分

        String money1_1 = (new StringBuffer(money1).reverse()).toString();//字符串倒序

        String money2 = decimalString.substring(pointPosition + 1);    //小數(shù)點之后的部分

        //異常處理

        for (int i = 0; i < money1.length(); i++) {

            if (!Character.isDigit(money1.charAt(i))) {

                return "數(shù)字中含有非法字符";

            }

        }

        for (int i = 0; i < money2.length(); i++) {

            if (!Character.isDigit(money2.charAt(i))) {

                return "數(shù)字中含有非法字符";

            }

        }

        if (money2.length() < 2) {                    //如果小數(shù)點后的部分少于兩位犯助,用"0"補齊

            if (money2.length() == 0) {

                money2 = "00";

            } else {

                money2 += "0";

            }

        } else {

            //如果小數(shù)點后的位數(shù)大于2位瞳抓,則只前2位

            money2 = decimalString.substring(pointPosition + 1, pointPosition + 3);

        }

        int len = money1_1.length();            //字符串反轉之后,小數(shù)點之前的字符位數(shù)

        int pos = len - 1;

        String sigle = "";

        boolean allhavenum = false;

        boolean havenum = false;

        boolean mark = false;                    //設置一個開關變量军洼,若當前數(shù)為"0"玫荣,將該值設為true甚淡;不為"0"時設為false

        /**以下代碼為讀出小數(shù)點左面的部分*/

        while (pos >= 0) {

            sigle = money1_1.substring(pos, pos + 1);//截取1位數(shù)字,比如數(shù)字1234.56,將左側的字符串反轉捅厂,值為4321贯卦,則截取的值為1

            /**讀取“億單元”的代碼。

             * 假設讀取10024531042.34焙贷。

             * 小數(shù)點左面反轉后為:24013542001

             * pos的初始值為10

             * mark的初始值為false

             * havenum的初始值為false

             * */

            if (pos >= 8 && pos < 12) {

                if (!sigle.equals("0")) {         //如果當前值不為"0"

                    if (!mark) {                 //如果當前值的前一位數(shù)不為"0"

                        formatDecimalString += numberCNN[Integer.parseInt(sigle)] + submoneyCN[pos % 4];

                    } else {                         //如果當前值不為"0"撵割,但該值的前一位數(shù)為"0"

                        if (allhavenum) {             //如果在當前值之前有不為"0"的數(shù)字出現(xiàn)。該條件用來處理用戶輸入的如:0012.34的數(shù)值

                            formatDecimalString += "零";

                        }

                        formatDecimalString += numberCNN[Integer.parseInt(sigle)] + submoneyCN[pos % 4];

                        mark = false;

                    }

                    havenum = true;

                    allhavenum = true;            //變量allhavenum表示小數(shù)點左面的數(shù)中是否有不為"0"的數(shù)字辙芍;true表示有啡彬,false表示無

                } else {                            //如果當前值為"0"

                    mark = true;

                }

                if (pos % 4 == 0 && havenum) {            //如果當前數(shù)字為該單元的最后一位,并且該單元中有不為"0"的數(shù)字出現(xiàn)

                    formatDecimalString += "億";

                    havenum = false;

                }

            }

            /**讀取“萬單元”的代碼*/

            if (pos >= 4 && pos < 8) {

                if (!sigle.equals("0")) {

                    if (!mark) {

                        formatDecimalString += numberCNN[Integer.parseInt(sigle)] + submoneyCN[pos % 4];

                    } else {

                        if (allhavenum) {

                            formatDecimalString += "零";

                        }

                        formatDecimalString += numberCNN[Integer.parseInt(sigle)] + submoneyCN[pos % 4];

                        mark = false;

                    }

                    havenum = true;

                    allhavenum = true;

                } else {

                    mark = true;

                }

                if (pos % 4 == 0 && havenum) {

                    formatDecimalString += "萬";

                    havenum = false;

                }

            }

            /**讀取“個故硅、十庶灿、百、千”的代碼*/

            if (pos >= 0 && pos < 4) {

                if (!sigle.equals("0")) {

                    if (!mark) {

                        formatDecimalString += numberCNN[Integer.parseInt(sigle)] + submoneyCN[pos % 4];

                    } else {

                        if (allhavenum) {

                            formatDecimalString += "零";

                        }

                        formatDecimalString += numberCNN[Integer.parseInt(sigle)] + submoneyCN[pos % 4];

                        mark = false;

                    }

                    havenum = true;

                    allhavenum = true;

                } else {

                    mark = true;

                }

            }

            pos--;

        }

        /**碰到小數(shù)點時的讀法*/

        if (allhavenum) { //如:00.34就不能讀為:元3角4分.變量allhavenum表示小數(shù)點左面的內容中是否有數(shù)字出現(xiàn)

            formatDecimalString += "元";

        } else {//如果小數(shù)點左面的部分都為0如:00.34應讀為:零元3角4分

            formatDecimalString = "零元";

        }

        /**以下代碼為讀出小數(shù)點右面的部分 */

        if (money2.equals("00")) {

            formatDecimalString += "整";

        } else {

            /**讀出角,如120.34讀為:1佰2拾元零3角4分吃衅;123.04讀為:1佰2拾3元零4分*/

//                if(money2.startsWith("0")||(allhavenum&&money1.endsWith("0"))){

//                    formatCN+="零";

//                }

            if (!money2.startsWith("0")) {

                formatDecimalString += numberCNN[Integer.parseInt(money2.substring(0, 1))] + "角";

            }

            //讀出分往踢,如:12.30讀1拾2元3角零分

            formatDecimalString += numberCNN[Integer.parseInt(money2.substring(1))] + "分";

        }

        return formatDecimalString;

    }

    /**

     * 整數(shù)轉換

     *

     * @param integerString 整數(shù)字符串(例:123456789   壹億貳仟叁佰肆拾伍萬陸仟柒佰捌拾玖元整)

     * @return 轉換后的大寫金額

     */

    private String integerConversion(String integerString) {

        //用來存放轉換后的大寫數(shù)字,因為是StringBuffer類型,所以順便把沒有轉換

        //的數(shù)字倒序排列一下,省一個變量.

        StringBuffer ChineseCharI = new StringBuffer(integerString);

        //倒序的數(shù)字,便于同單位合并

        String rintString = ChineseCharI.reverse().toString();

        //清空一下

        ChineseCharI.delete(0, ChineseCharI.length());

        //單位索引

        int unitIndex = 0;

        //數(shù)字長度

        int intStringLen = integerString.length();

        //一位由字符轉換的數(shù)字

        int intStringnumber = 0;

        //補0

        boolean addZero = false;

        boolean flagZero = false;

        for (int i = 0; i < intStringLen; i++) {

            //按單位長度循環(huán)索引

            unitIndex = i % UNIT.length;

            //異常處理

            if (!Character.isDigit(rintString.charAt(i))) {

                return "數(shù)字中含有非法字符";

            }

            //將字符轉為數(shù)字,范圍為10以內(不包括10徘层,超出則返回-1)

            intStringnumber = Character.digit(rintString.charAt(i), 10);

            //如果當前位是0,開啟補0繼續(xù)循環(huán)直到不是0的位

            if (intStringnumber == 0) {

                addZero = true;

                if (i != 0 && i % 4 == 0) {

                    if (addZero && ChineseCharI.length() != 0) {

                        ChineseCharI.append(TEMPLATE[0]);

                        addZero = false;

                    }

                    flagZero = true;

                    ChineseCharI.append(UNIT[unitIndex]);

                }

            } else {

                //若當前位不是第一位且補0開啟

                if (addZero && ChineseCharI.length() != 0 && !flagZero) {

                    ChineseCharI.append(TEMPLATE[0]);

                }

                flagZero = false;

                //插入單位

                //個位數(shù)后面不需要單位

                if (i > 0) {

                    ChineseCharI.append(UNIT[unitIndex]);

                }

                //插入大寫數(shù)字

                ChineseCharI.append(TEMPLATE[intStringnumber]);

                //補0關閉

                addZero = false;

            }

        }

        //異常處理

        if (ChineseCharI.length() == 0) {

            return "零";

        }

        return ChineseCharI.reverse().toString() + "元整";

    }

}

在項目中的應用:

String convert = MoneyFormatUtil.getInstance().convert("1234567.89");

String convert1 = MoneyFormatUtil.getInstance().convert("1.34");

String convert2 = MoneyFormatUtil.getInstance().convert("100.34");

String convert3 = MoneyFormatUtil.getInstance().convert("34f5460.34");

String convert4 = MoneyFormatUtil.getInstance().convert("10000.34");

String convert5 = MoneyFormatUtil.getInstance().convert("100000.34f");

String convert6 = MoneyFormatUtil.getInstance().convert("1003430000.34");

String convert7 = MoneyFormatUtil.getInstance().convert("1101010101.34");

String convert8 = MoneyFormatUtil.getInstance().convert("1010101010.34");

早計劃峻呕,早準備,早完成惑灵。 歡迎關注!交流眼耀!Star英支!

GitHub:https://github.com/wangyang0313

微信公眾號:一個靈活的胖子MrWang

CSDN:https://blog.csdn.net/qq941263013

20200430145304899.jpg
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市哮伟,隨后出現(xiàn)的幾起案子干花,更是在濱河造成了極大的恐慌,老刑警劉巖楞黄,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件池凄,死亡現(xiàn)場離奇詭異,居然都是意外死亡鬼廓,警方通過查閱死者的電腦和手機肿仑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人尤慰,你說我怎么就攤上這事馏锡。” “怎么了伟端?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵杯道,是天一觀的道長。 經常有香客問我责蝠,道長党巾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任霜医,我火速辦了婚禮齿拂,結果婚禮上,老公的妹妹穿的比我還像新娘支子。我一直安慰自己创肥,他們只是感情好,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布值朋。 她就那樣靜靜地躺著叹侄,像睡著了一般。 火紅的嫁衣襯著肌膚如雪昨登。 梳的紋絲不亂的頭發(fā)上趾代,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機與錄音丰辣,去河邊找鬼撒强。 笑死,一個胖子當著我的面吹牛笙什,可吹牛的內容都是我干的飘哨。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼琐凭,長吁一口氣:“原來是場噩夢啊……” “哼芽隆!你這毒婦竟也來了?” 一聲冷哼從身側響起统屈,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤胚吁,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后愁憔,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體腕扶,經...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年吨掌,在試婚紗的時候發(fā)現(xiàn)自己被綠了半抱。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脓恕。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖代虾,靈堂內的尸體忽然破棺而出进肯,到底是詐尸還是另有隱情,我是刑警寧澤棉磨,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布江掩,位于F島的核電站,受9級特大地震影響乘瓤,放射性物質發(fā)生泄漏环形。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一衙傀、第九天 我趴在偏房一處隱蔽的房頂上張望抬吟。 院中可真熱鬧,春花似錦统抬、人聲如沸火本。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽钙畔。三九已至,卻和暖如春金麸,著一層夾襖步出監(jiān)牢的瞬間擎析,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工挥下, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留揍魂,地道東北人。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓棚瘟,卻偏偏與公主長得像现斋,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子偎蘸,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,097評論 1 32
  • 有了第一天的經驗庄蹋,我與Elsile老師在第二天夏令營的工作里,更加暢順與默契禀苦。 今天戶外的重頭戲是參觀鎮(zhèn)上的博物館...
    桐珈語閱讀 284評論 0 1
  • 小確幸就是你喜歡的人也剛好喜歡你蔓肯,不遲不早剛剛好相互喜歡著遂鹊。 青春年少時每個少女心里都駐著像歐陽非凡或者徐太宇...
    b4ba1850314e閱讀 313評論 0 0
  • 想起二十年前自己做傳銷的一幕:每天早上對著鏡子振乏,指著自己,一遍一遍地說秉扑,你是最棒的慧邮,你是最棒的……调限。從開始的小聲,...
    龍暢天下閱讀 446評論 2 4
  • #感恩日記# Day10 1.感恩旸丁女神的分享误澳,演講讓生活越來越美好耻矮,利用演講中的prs結構助力職場,熱愛演講的...
    曉丹成長說閱讀 301評論 0 1