├── CHANGELOG.md
├── psalm.xml.dist
├── LICENSE.md
├── .php_cs.dist.php
├── composer.json
├── README.md
└── src
└── RmbCapital.php
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to `rmb-capital` will be documented in this file.
4 |
5 | ## 1.0.0 - 2021-05-20
6 |
7 | - initial release
8 |
--------------------------------------------------------------------------------
/psalm.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) chuoke
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.php_cs.dist.php:
--------------------------------------------------------------------------------
1 | in([
5 | __DIR__ . '/src',
6 | __DIR__ . '/tests',
7 | ])
8 | ->name('*.php')
9 | ->notName('*.blade.php')
10 | ->ignoreDotFiles(true)
11 | ->ignoreVCS(true);
12 |
13 | return (new PhpCsFixer\Config())
14 | ->setRules([
15 | '@PSR2' => true,
16 | 'array_syntax' => ['syntax' => 'short'],
17 | 'ordered_imports' => ['sort_algorithm' => 'alpha'],
18 | 'no_unused_imports' => true,
19 | 'not_operator_with_successor_space' => true,
20 | 'trailing_comma_in_multiline' => true,
21 | 'phpdoc_scalar' => true,
22 | 'unary_operator_spaces' => true,
23 | 'binary_operator_spaces' => true,
24 | 'blank_line_before_statement' => [
25 | 'statements' => ['break', 'continue', 'declare', 'return', 'throw', 'try'],
26 | ],
27 | 'phpdoc_single_line_var_spacing' => true,
28 | 'phpdoc_var_without_name' => true,
29 | 'method_argument_space' => [
30 | 'on_multiline' => 'ensure_fully_multiline',
31 | 'keep_multiple_spaces_after_comma' => true,
32 | ],
33 | 'single_trait_insert_per_statement' => true,
34 | ])
35 | ->setFinder($finder);
36 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "chuoke/rmb-capital",
3 | "description": "阿拉伯数字金额转为汉字大写",
4 | "keywords": [
5 | "人民币",
6 | "大写",
7 | "汉字金额"
8 | ],
9 | "homepage": "https://github.com/chuoke/rmb-capital",
10 | "license": "MIT",
11 | "authors": [
12 | {
13 | "name": "chuoke",
14 | "email": "chuokechungyoung@gmail.com",
15 | "role": "Developer"
16 | }
17 | ],
18 | "require": {
19 | "php": "^7.1|^8"
20 | },
21 | "require-dev": {
22 | "friendsofphp/php-cs-fixer": "^2.17",
23 | "phpunit/phpunit": "^7|^8|^9",
24 | "vimeo/psalm": "^4.3"
25 | },
26 | "autoload": {
27 | "psr-4": {
28 | "Chuoke\\RmbCapital\\": "src"
29 | }
30 | },
31 | "autoload-dev": {
32 | "psr-4": {
33 | "Chuoke\\RmbCapital\\Tests\\": "tests"
34 | }
35 | },
36 | "scripts": {
37 | "psalm": "vendor/bin/psalm",
38 | "test": "vendor/bin/phpunit",
39 | "test-coverage": "vendor/bin/phpunit --coverage-html coverage",
40 | "format": "vendor/bin/php-cs-fixer fix --allow-risky=yes"
41 | },
42 | "config": {
43 | "sort-packages": true
44 | },
45 | "minimum-stability": "dev",
46 | "prefer-stable": true
47 | }
48 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Convert RMB amount to Chinese uppercase.
2 |
3 | [](https://packagist.org/packages/chuoke/rmb-capital)
4 | [](https://github.com/chuoke/rmb-capital/actions/workflows/run-tests.yml)
5 | [](https://github.com/chuoke/rmb-capital/actions/workflows/php-cs-fixer.yml)
6 | [](https://packagist.org/packages/chuoke/rmb-capital)
7 |
8 | ---
9 |
10 | 将阿拉伯金额数字转换为汉字大写形式。
11 |
12 | ---
13 |
14 | ## 安装
15 |
16 | 使用 Composer 安装:
17 |
18 | ```bash
19 | composer require chuoke/rmb-capital
20 | ```
21 |
22 | ## 使用
23 |
24 | ```php
25 | $rmbCapital = new Chuoke\RmbCapital\RmbCapital();
26 |
27 | echo $rmbCapital->convert(123456789.01);
28 | // 人民币壹亿贰仟叁佰肆拾伍万陆仟柒佰捌拾玖元零壹分
29 | ```
30 |
31 | 如果不需要返回”人民币“ 前缀
32 |
33 | ```php
34 | $rmbCapital->withoutPrefix()->convert(123456789.01);
35 | // 壹亿贰仟叁佰肆拾伍万陆仟柒佰捌拾玖元零壹分
36 | ```
37 |
38 | > 在转换前一定确保数字的正确性。最大金额到万亿级。
39 |
40 | ---
41 |
42 | ## 规范
43 |
44 | 详查 《会计基础工作规范》,此处总结性的罗列关键点。
45 |
46 | - 所有以元为单位
47 | - 汉字大写数字金额如:零、壹、贰、叁、肆、伍、陆、柒、捌、玖、拾、佰、仟、万、亿等
48 | - 大写金额数字到元或者角为止的,在“元”或者“角”字之后应当写“整”字或者“正”字(本项目使用“整”),大写金额数字有分的,分字后面不写“整”或者“正”字
49 | - 大写金额数字前未印有货币名称的,应当加填货币名称,即“人民币”,货币名称与金额数字之间不得留有空白
50 | - 阿拉伯金额数字中间有“0”时,汉字大写金额要写“零”字
51 | - 阿拉伯数字金额中间连续有几个“0”时,汉字大写金额中可以只写一个“零”字;
52 | 阿拉伯金额数字元位是“0”,或者数字中间连续有几个“0”、元位也是“0”但角位不是 “0”时,汉字大写金额可以只写一个“零”字,也可以不写“零”字
53 |
54 | ---
55 |
56 | ## License
57 |
58 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
59 |
--------------------------------------------------------------------------------
/src/RmbCapital.php:
--------------------------------------------------------------------------------
1 | usePrefix = false;
51 |
52 | return $this;
53 | }
54 |
55 | /**
56 | * 进行大写转换
57 | *
58 | * @param int|float|string $amount
59 | * @return string
60 | */
61 | public function convert($amount)
62 | {
63 | // 转换整数部分
64 | $integerResult = $this->convertInteger($amount);
65 |
66 | // 转换小数位
67 | $decimalResult = $this->convertDecimal($amount);
68 |
69 | // 没有则为 零元
70 | // 注意,类似:0.07元,应为 人民币柒分
71 | if (! $integerResult && ! $decimalResult) {
72 | $integerResult .= $this->capitalNumber(0);
73 | }
74 |
75 | // 整数位后要跟元
76 | if ($integerResult) {
77 | $integerResult .= '元';
78 | }
79 |
80 | if (! $decimalResult) {
81 | $integerResult .= '整';
82 | }
83 |
84 | if (strpos((string) $amount, '-') === 0) {
85 | $integerResult = '负' . $integerResult;
86 | }
87 |
88 | return ($this->usePrefix ? $this->prefix : '') . $integerResult . $decimalResult;
89 | }
90 |
91 | /**
92 | * 转换整数部分
93 | *
94 | * @param int|float|string $amount
95 | * @return string
96 | */
97 | protected function convertInteger($amount)
98 | {
99 | $parts = explode('.', (string) $amount);
100 | $integer = trim($parts[0] ?? '', '-');
101 |
102 | $result = [];
103 |
104 | // 反着按日常习惯,从个位开始转换
105 | $integerNumbers = $integer ? array_reverse(str_split($integer)) : [];
106 |
107 | // 阿拉伯金额数字中间有“0”时,汉字大写金额要写“零”字;
108 | // 数字中间连续有几个“0”,汉字大写金额可以只写一个“零”字
109 |
110 | $last = null;
111 | foreach (array_chunk($integerNumbers, 4) as $chunkKey => $chunk) {
112 | if (! ((int) implode('', $chunk))) {
113 | // 全是 0 则直接跳过
114 | continue;
115 | }
116 |
117 | array_unshift($result, $this->placeUnits[$chunkKey]);
118 |
119 | foreach ($chunk as $key => $number) {
120 | // 去除重复 零,以及第一位的 零,类似:1002、110,应为 壹仟零贰元整、壹佰壹拾元整
121 | if (! $number && (! $last || $key === 0)) {
122 | $last = $number;
123 |
124 | continue;
125 | }
126 | $last = $number;
127 |
128 | // 类似 1022,应为 壹仟零贰拾贰元整,中间的 0 是不需要 佰 的
129 | if ($number) {
130 | array_unshift($result, $this->integerUnits[$key]);
131 | }
132 |
133 | array_unshift($result, $this->capitalNumber((int) $number));
134 | }
135 | }
136 |
137 | return implode('', $result);
138 | }
139 |
140 | /**
141 | * 转换小数部分
142 | *
143 | * @param int|float|string $amount
144 | *
145 | * @return string
146 | */
147 | protected function convertDecimal($amount)
148 | {
149 | $result = [];
150 |
151 | $parts = explode('.', (string) $amount);
152 | $integer = trim($parts[0] ?? '', '-');
153 | $decimal = $parts[1] ?? '';
154 |
155 | if (! ((int) $decimal)) {
156 | $decimal = '';
157 | }
158 |
159 | $decimalNumbers = $decimal ? str_split($decimal) : [];
160 | $jiao = (int) array_shift($decimalNumbers); // 角比较特殊
161 |
162 | if ($jiao) {
163 | array_push($result, $this->capitalNumber($jiao), $this->decimalUnits[0]);
164 |
165 | if (! count(array_filter($decimalNumbers))) {
166 | array_push($result, '整');
167 | }
168 | } else {
169 | // 如:0.07元,应为 人民币柒分
170 | // 而类似 23.05 应为 贰拾叁元零伍分
171 | if (count(array_filter($decimalNumbers)) && $integer) {
172 | array_push($result, $this->capitalNumber(0));
173 | }
174 | }
175 |
176 | foreach ($decimalNumbers as $key => $number) {
177 | if ($number) {
178 | array_push($result, $this->capitalNumber((int) $number), $this->decimalUnits[$key + 1]);
179 | }
180 | }
181 |
182 | return implode('', $result);
183 | }
184 |
185 | /**
186 | * 获取数字的大写
187 | *
188 | * @param int $number
189 | * @return string
190 | */
191 | public function capitalNumber(int $number)
192 | {
193 | return $this->capitalNumbers[$number] ?? '';
194 | }
195 | }
196 |
--------------------------------------------------------------------------------