数字转金额容易忽略的一点

146 阅读3分钟

number-zh 现在已经发布了,欢迎试用。

阿拉伯数字转人民币大写金额应该还是一个比较简单的需求,需要注意的就这么几点:

  1. 中文数字大写,不能使用中文小写一二三等。
  2. 数字的数字阅读习惯遵循汉语读数原则。
  3. 人民币单位是元或者圆。
  4. 金额在元和角之后要加正或者整,角之后可以不加,一般来讲分是金额的最小单位。

这是我们的大致印象,但是我们写库要力求准确,所以还是应该看这方面的标准,我之前写过文章——金额大写数字规范指南

我依据分节读数法来实现中文大写金额的整数部分,写着写着发现漏掉了一个细节。

分节读数法可参考我另外两篇文章:重学数字——分节读数法简体中文大数如何读

那就是阿拉伯数字中出现零的处理,规范有很重要的两条,第一条和第三条:

(一)阿拉伯数字中间有“0”时,中文大写金额要写“零”字。如¥1,409.50,应写成人民币壹仟肆佰零玖元伍角。 (二)阿拉伯数字中间连续有几个“0”时,中文大写金额中间可以只写一个“零”字。如¥6,007.14,应写成人民币陆仟零柒元壹角肆分。 (三)阿拉伯金额数字万位或元位是“0”,或者数字中间连续有几个“0”,万位、元位也是“0”,但千位、角位不是“0”时,中文大写金额中可以只写一个零字,也可以不写“零”字。如¥1,680.32,应写成人民币壹仟陆佰捌拾元零叁角贰分,或者写成人民币壹仟陆佰捌拾元叁角贰分;又如¥107,000.53,应写成人民币壹拾万柒仟元零伍角叁分,或者写成人民币壹拾万零柒仟元伍角叁分。

阿拉伯数字中间有「0」时,零要读出来,比如 109000 读作一十万零九千。事实上,我们根本不会这么读,数级万前面的零,读的时候我们都是省略的,正确是一十万九千,即使是严格分节读数,数位上的零要读出来,也是一十零万九千 而不是 一十万零九千,后面这种是错误读法。

规则的制定者可能意识到了这个问题,所以补充了第三条,让这个零可以省略也可以不省略,而第三条作为补充说明只是讲到了万级,如果写到亿级的话,这个零可就难了,写的时候一个头两个大。

很明显,当时制定这份规定的人,数学没有学好,才会导致在如此重要的事情上犯了错误。


为了处理数级的个位是零,上一个数级的千位不是零,零可以省略,可以出现在数级的前面和后面,我针对阿拉伯数字转中文 number-to-zh 增加了两个参数 hangingZerosBeforeDigits 和 hangingZerosAfterDigits。用来控制上面三种情况,默认这两个参数都是 false。

  1. 默认 109000 读作一十万九千
  2. hangingZerosBeforeDigits 是 true,109000 读作一十零万九千
  3. hangingZerosAfterDigits 是 true,109000 读作一十万零九千

现在看应该把 hangingZerosBeforeDigits 和 hangingZerosAfterDigits 合并成一个参数,叫做 hangingZerosAroundDigits,它的值是 "before""after"false

/**
 * @default false
 * @description 数级的个位是零,上一个数级的千位不是零,零可以有三种写法,false:零省略,before:零出现在数级前面,after:零出现在数级的后面(人民银行规定的错误写法)。
 * @example
 * false  205000 => 二十万五千
 * before 205000 => 二十{零}万五千
 * after  205000 => 二十万{零}五千
 */
hangingZerosAroundDigits?: false | "before" | "after";