• python 实现金额数字转成大写


    原文:https://www.cnblogs.com/kearney908/p/7085999.html

    改造:把处理0的注释掉,避免出现【0角一分】等情况

    def cncurrency(value, capital=True, prefix=False, classical=None):
        '''
        参数:
        capital:    True   大写汉字金额
                    False  一般汉字金额
        classical:  True   元
                    False  圆
        prefix:     True   以'人民币'开头
                    False, 无开头
        '''
        if not isinstance(value, (Decimal, str, int)):
            msg = '''
            由于浮点数精度问题,请考虑使用字符串,或者 decimal.Decimal 类。
            因使用浮点数造成误差而带来的可能风险和损失作者概不负责。
            '''
            warnings.warn(msg, UserWarning)
        # 默认大写金额用圆,一般汉字金额用元
        if classical is None:
            classical = True if capital else False
    
        # 汉字金额前缀
        if prefix is True:
            prefix = '人民币'
        else:
            prefix = ''
    
        # 汉字金额字符定义
        dunit = ('', '')
        if capital:
            num = ('', '', '', '', '', '', '', '', '', '')
            iunit = [None, '', '', '', '', '', '', '', '亿', '', '', '', '', '', '', '']
        else:
            num = ('', '', '', '', '', '', '', '', '', '')
            iunit = [None, '', '', '', '', '', '', '', '亿', '', '', '', '', '', '', '']
        if classical:
            iunit[0] = '' if classical else ''
        # 转换为Decimal,并截断多余小数
    
        if not isinstance(value, Decimal):
            value = Decimal(value).quantize(Decimal('0.01'))
    
        # 处理负数
        if value < 0:
            prefix += ''  # 输出前缀,加负
            value = - value  # 取正数部分,无须过多考虑正负数舍入
            # assert - value + value == 0
        # 转化为字符串
        s = str(value)
        if len(s) > 19:
            raise ValueError('金额太大了,不知道该怎么表达。')
        istr, dstr = s.split('.')  # 小数部分和整数部分分别处理
        istr = istr[::-1]  # 翻转整数部分字符串
        so = []  # 用于记录转换结果
    
        #
        if value == 0:
            return prefix + num[0] + iunit[0]
        haszero = False  # 用于标记零的使用
        if dstr == '00':
            haszero = True  # 如果无小数部分,则标记加过零,避免出现“圆零整”
    
        # 处理小数部分
        #
        if dstr[1] != '0':
            so.append(dunit[1])
            so.append(num[int(dstr[1])])
        else:
            so.append('')  # 无分,则加“整”
        #
        if dstr[0] != '0':
            so.append(dunit[0])
            so.append(num[int(dstr[0])])
        elif dstr[1] != '0':
            # so.append(num[0])  # 无角有分,添加“零”
            # haszero = True  # 标记加过零了
            pass
    
        # 无整数部分
        if istr == '0':
            if haszero:  # 既然无整数部分,那么去掉角位置上的零
                so.pop()
            so.append(prefix)  # 加前缀
            so.reverse()  # 翻转
            return ''.join(so)
    
        # 处理整数部分
        for i, n in enumerate(istr):
            n = int(n)
            if i % 4 == 0:  # 在圆、万、亿等位上,即使是零,也必须有单位
                if i == 8 and so[-1] == iunit[4]:  # 亿和万之间全部为零的情况
                    so.pop()  # 去掉万
                so.append(iunit[i])
                if n == 0:  # 处理这些位上为零的情况
                    # if not haszero:  # 如果以前没有加过零
                        # so.insert(-1, num[0])  # 则在单位后面加零
                        # haszero = True  # 标记加过零了
                    pass
                else:  # 处理不为零的情况
                    so.append(num[n])
                    haszero = False  # 重新开始标记加零的情况
            else:  # 在其他位置上
                if n != 0:  # 不为零的情况
                    so.append(iunit[i])
                    so.append(num[n])
                    haszero = False  # 重新开始标记加零的情况
                else:  # 处理为零的情况
                    if not haszero:  # 如果以前没有加过零
                        # so.append(num[0])
                        # haszero = True
                        pass
    
        # 最终结果
        so.append(prefix)
        so.reverse()
        return ''.join(so)
  • 相关阅读:
    PartialView
    常用取默认值
    迁移环境或升级正常功能出bug常见原因
    模拟登陆语法
    fsg报表相关
    常用数组定义方式
    to_char函数 官方文档详解(数字格式转换和日期转换)
    个人工作window10常用快捷键
    ebs常见概念解释
    常用ASCII码和字符的转换
  • 原文地址:https://www.cnblogs.com/dannyyao/p/12171435.html
Copyright © 2020-2023  润新知