├── 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 | [![Latest Version on Packagist](https://img.shields.io/packagist/v/chuoke/rmb-capital.svg?style=flat-square)](https://packagist.org/packages/chuoke/rmb-capital) 4 | [![Tests](https://github.com/chuoke/rmb-capital/actions/workflows/run-tests.yml/badge.svg)](https://github.com/chuoke/rmb-capital/actions/workflows/run-tests.yml) 5 | [![Check & fix styling](https://github.com/chuoke/rmb-capital/actions/workflows/php-cs-fixer.yml/badge.svg)](https://github.com/chuoke/rmb-capital/actions/workflows/php-cs-fixer.yml) 6 | [![Total Downloads](https://img.shields.io/packagist/dt/chuoke/rmb-capital.svg?style=flat-square)](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 | --------------------------------------------------------------------------------