├── CHANGELOG.md
├── LICENSE.md
├── README.md
├── composer.json
└── src
├── Concerns
├── Collapse.php
├── NumberResolver.php
├── TripletTransformer.php
└── TripletsConverter.php
├── Dictionary.php
├── DictionaryInterface.php
├── SouthDictionary.php
└── Transformer.php
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | Tất cả lịch sử tiến trình phát triển thư viện
4 |
5 | # 1.3.0
6 |
7 | - Cho phép thay đổi cách đọc phần thập phân.
8 |
9 | # 1.2.1
10 |
11 | - Hổ trợ PHP8.
12 |
13 | # 1.2.0
14 |
15 | - Xóa phương thức trừu tượng `getDictionary` trong `Concerns\TripletTransformer`.
16 | - Tổ chức lại cấu trúc code.
17 |
18 | # 1.1.0
19 |
20 | - Xóa phương thức `resolve` trong `Transfomer`.
21 | - Tổ chức lại cấu trúc code.
22 |
23 | # 1.0.5
24 |
25 | - Thêm concern `NumberResolver`.
26 |
27 | # 1.0.4
28 |
29 | - Cập nhật verify input tại phương thức `resolve` của lớp `Transfomer`.
30 |
31 | # 1.0.3
32 |
33 | - Sửa lỗi khi chuyển đổi phân số âm có số nguyên là 0.
34 |
35 | # 1.0.2
36 |
37 | - Sửa lỗi khi chuyển đổi phân số có số nguyên là 0.
38 |
39 | # 1.0.1
40 |
41 | - Sửa đơn vị tính trong từ điển miền Nam.
42 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) PHP Viet
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Number To Words
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | ## Thông tin
18 |
19 | Thư viện hổ trợ chuyển đổi số sang chữ số Tiếng Việt.
20 |
21 | ## Cài đặt
22 |
23 | Cài đặt Number To Words thông qua [Composer](https://getcomposer.org):
24 |
25 | ```bash
26 | composer require phpviet/number-to-words
27 | ```
28 |
29 | ## Cách sử dụng
30 |
31 | ### Tích hợp sẵn trên các framework phổ biến hiện tại
32 |
33 | - [`Laravel`](https://github.com/phpviet/laravel-number-to-words)
34 | - [`Symfony`](https://github.com/phpviet/symfony-number-to-words)
35 | - [`Yii`](https://github.com/phpviet/yii-number-to-words)
36 |
37 | hoặc nếu bạn muốn sử dụng không dựa trên framework thì tiếp tục xem tiếp.
38 |
39 | ### Các tính năng của thư viện:
40 |
41 | - [`Chuyển đổi số sang chữ số`](#Chuyển-đổi-số-sang-chữ-số)
42 | - [`Chuyển đổi số sang tiền tệ`](#Chuyển-đổi-số-sang-tiền-tệ)
43 | - [`Thay cách đọc số`](#Thay-cách-đọc-số)
44 |
45 | ### Chuyển đổi số sang chữ số
46 |
47 | Thư viện cung cấp cho chúng ta lớp `PHPViet\NumberToWords\Transformer` để thực hiện việc chuyển đổi
48 | thông qua phương thức `toWords` của đối tượng:
49 |
50 | ```php
51 |
52 | use PHPViet\NumberToWords\Transformer;
53 |
54 | $transformer = new Transformer();
55 |
56 | // âm năm
57 | $transformer->toWords(-5);
58 |
59 | // năm
60 | $transformer->toWords(5);
61 |
62 | // năm phẩy năm
63 | $transformer->toWords(5.5);
64 |
65 | // mười lăm
66 | $transformer->toWords(15);
67 |
68 | // một trăm linh năm
69 | $transformer->toWords(105);
70 |
71 | // bốn
72 | $transformer->toWords(4);
73 |
74 | // mười bốn
75 | $transformer->toWords(14);
76 |
77 | // hai mươi tư
78 | $transformer->toWords(24);
79 |
80 | // một trăm ba mươi tư
81 | $transformer->toWords(134);
82 |
83 | // một
84 | $transformer->toWords(1); // một
85 |
86 | // mười một
87 | $transformer->toWords(11);
88 |
89 | // hai mươi mốt
90 | $transformer->toWords(21);
91 |
92 | // một trăm nghìn không trăm hai mươi mốt.
93 | $transformer->toWords(100021);
94 |
95 | // một trăm ba mươi mốt triệu không trăm năm mươi nghìn không trăm ba mươi lăm
96 | $transformer->toWords(131050035);
97 |
98 | ```
99 |
100 | ### Chuyển đổi số sang tiền tệ
101 |
102 | Cũng như cách sử dụng của chuyển số sang chữ số ta cũng sử dụng lớp `PHPViet\NumberToWords\Transformer`
103 | để thực thi tác vụ:
104 |
105 | ```php
106 |
107 | use PHPViet\NumberToWords\Transformer;
108 |
109 | $transformer = new Transformer();
110 |
111 | // năm triệu sáu trăm chín mươi nghìn bảy trăm đồng
112 | $transformer->toCurrency(5690700);
113 |
114 | // chín mươi lăm triệu năm trăm nghìn hai trăm đồng
115 | $transformer->toCurrency(95500200);
116 |
117 | // tám trăm năm mươi tư triệu chín trăm đồng
118 | $transformer->toCurrency(854000900);
119 |
120 | ```
121 | Trong một số loại tiền tệ, bạn cần thay đổi cách đọc theo đơn vị quy đổi, ví dụ 1 đô = 100 xen
122 | ```php
123 | use PHPViet\NumberToWords\Transformer;
124 |
125 | // Đặt số chữ số phần thập phân (tham số đầu tiên Dictionary có thể null)
126 | $transformer = new Transformer(null, 2);
127 |
128 | // năm mươi sáu đô chín mươi xen, thay vì năm mươi sáu đô chín xen
129 | $transformer->toCurrency(56.90);
130 | ```
131 |
132 | Ngoài ra ta còn có thể sử dụng đơn vị tiền tệ khác thông qua tham trị thứ 2 của phương thức
133 | `toCurrency`, với mảng phần từ đầu tiên là đơn vị cho số nguyên và kế tiếp là đơn vị của phân số:
134 |
135 | ```php
136 |
137 | use PHPViet\NumberToWords\Transformer;
138 |
139 | $transformer = new Transformer();
140 |
141 | // sáu nghìn bảy trăm bốn mươi hai đô bảy xen
142 | $transformer->toCurrency(6742.7, ['đô', 'xen']);
143 |
144 | // chín nghìn bốn trăm chín mươi hai đô mười lăm xen
145 | $transformer->toCurrency(9492.15, ['đô', 'xen']);
146 |
147 | // tám nghìn ba trăm sáu mươi mốt đô bốn xen
148 | $transformer->toCurrency('8361.40', ['đô', 'xen']);
149 | ```
150 |
151 | ### Thay cách đọc số
152 |
153 | Trong thư viện ngoài cách đọc tiêu chuẩn còn hổ trợ cho chúng ta lớp `PHPViet\NumberToWords\SouthDictionary`
154 | giúp đọc số theo phong cách trong Nam:
155 |
156 | ```php
157 |
158 | use PHPViet\NumberToWords\Transformer;
159 | use PHPViet\NumberToWords\SouthDictionary;
160 |
161 | $transformer = new Transformer();
162 | $southDictionary = new SouthDictionary();
163 | $southTransformer = new Transformer($southDictionary);
164 |
165 | $transformer->toWords(101); // một trăm linh một
166 | $southTransformer->toWords(101); // một trăm lẻ một
167 |
168 | $transformer->toWords(1000); // một nghìn
169 | $southTransformer->toWords(1000); // một ngàn
170 |
171 | $transformer->toWords(24) // hai mươi tư
172 | $southTransformer->toWords(24); // hai mươi bốn
173 |
174 | $transformer->toCurrency(124001); // một trăm hai mươi tư nghìn không trăm linh một
175 | $southTransformer->toCurrency(124001); // một trăm hai mươi bốn ngàn không trăm lẻ một
176 | ```
177 |
178 | Nếu như bạn muốn thay đổi cách đọc theo ý bạn thì hãy tạo một lớp `Dictionary` kế thừa
179 | `PHPViet\NumberToWords\Dictionary` hoặc thực thi mẫu trừu tượng `PHPViet\NumberToWords\DictionaryInterface`:
180 |
181 | ```php
182 |
183 | use PHPViet\NumberToWords\Dictionary;
184 | use PHPViet\NumberToWords\Transformer;
185 |
186 | class MyDictionary extends Dictionary {
187 |
188 | /**
189 | * @inheritDoc
190 | */
191 | public function specialTripletUnitFive(): string
192 | {
193 | return 'nhăm';
194 | }
195 |
196 | }
197 |
198 | $transformer = new Transformer();
199 | $myDictionary = new MyDictionary();
200 | $myTransformer = new Transformer($myDictionary);
201 |
202 | $transformer->toWords(15); // mười lăm
203 | $myTransformer->toWords(15); // mười nhăm
204 |
205 | ```
206 |
207 | ## Dành cho nhà phát triển
208 |
209 | Nếu như bạn cảm thấy thư viện còn thiếu sót hoặc sai sót và bạn muốn đóng góp để phát triển chung,
210 | chúng tôi rất hoan nghênh! Hãy tạo các `issue` để đóng góp ý tưởng cho phiên bản kế tiếp
211 | hoặc tạo `PR` để đóng góp. Cảm ơn!
212 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "phpviet/number-to-words",
3 | "type": "library",
4 | "description": "Thư viện hổ trợ chuyển đổi số sang chữ số.",
5 | "keywords": [
6 | "phpviet",
7 | "number-to-words"
8 | ],
9 | "homepage": "https://github.com/phpviet/number-to-words",
10 | "license": "MIT",
11 | "authors": [
12 | {
13 | "name": "Vuong Xuong Minh",
14 | "email": "vuongxuongminh@gmail.com"
15 | }
16 | ],
17 | "require": {
18 | "php": ">=7.1"
19 | },
20 | "require-dev": {
21 | "phpunit/phpunit": "~7.5",
22 | "scrutinizer/ocular": "^1.5"
23 | },
24 | "autoload": {
25 | "psr-4": {
26 | "PHPViet\\NumberToWords\\": "src"
27 | }
28 | },
29 | "autoload-dev": {
30 | "psr-4": {
31 | "PHPViet\\NumberToWords\\Tests\\": "tests"
32 | }
33 | },
34 | "scripts": {
35 | "test": "\"vendor/bin/phpunit\""
36 | },
37 | "config": {
38 | "sort-packages": true
39 | },
40 | "extra": {
41 | "branch-alias": {
42 | "dev-master": "1.0-dev"
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/Concerns/Collapse.php:
--------------------------------------------------------------------------------
1 |
13 | *
14 | * @since 1.2.0
15 | */
16 | trait Collapse
17 | {
18 | /**
19 | * Ghép mảng chữ số thành chuỗi.
20 | *
21 | * @param array|string[] $words
22 | * @return string
23 | *
24 | * @since 1.2.0
25 | */
26 | protected function collapseWords(array $words): string
27 | {
28 | $separator = $this->dictionary->separator();
29 | $words = array_filter($words);
30 |
31 | return implode($separator, $words);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/Concerns/NumberResolver.php:
--------------------------------------------------------------------------------
1 |
15 | *
16 | * @since 1.0.5
17 | */
18 | trait NumberResolver
19 | {
20 | /**
21 | * Chia số truyền vào thành mảng bao gồm kiểu số âm hoặc dương, số nguyên và phân số.
22 | *
23 | * @param int|float|string $number
24 | * @return array
25 | *
26 | * @throws InvalidArgumentException
27 | */
28 | protected function resolveNumber($number): array
29 | {
30 | if (! is_numeric($number)) {
31 | throw new InvalidArgumentException(sprintf('Number arg (`%s`) must be numeric!', $number));
32 | }
33 |
34 | if ($this->decimalPart === null) {
35 | $number += 0; // trick xóa các số 0 lẻ sau cùng của phân số đối với input là chuỗi.
36 | $number = (string) $number;
37 | } else {
38 | $number = number_format($number, $this->decimalPart, '.', '');
39 | }
40 | $minus = '-' === $number[0];
41 |
42 | if (false !== strpos($number, '.')) {
43 | $numbers = explode('.', $number, 2);
44 | } else {
45 | $numbers = [$number, 0];
46 | }
47 |
48 | return array_merge([$minus], array_map('abs', $numbers));
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/Concerns/TripletTransformer.php:
--------------------------------------------------------------------------------
1 |
13 | *
14 | * @since 1.0.0
15 | */
16 | trait TripletTransformer
17 | {
18 | /**
19 | * Chuyển đổi cụm 3 số thành chữ số.
20 | *
21 | * @param int $triplet
22 | * @param bool $isFirst
23 | * @param int $exponent
24 | * @return string
25 | */
26 | protected function tripletToWords(int $triplet, bool $isFirst, int $exponent): string
27 | {
28 | [$hundred, $ten, $unit] = $this->splitTriplet($triplet);
29 |
30 | if (0 < $hundred || ! $isFirst) {
31 | $words[] = $this->dictionary->getTripletHundred($hundred);
32 |
33 | if (0 === $ten && 0 < $unit) {
34 | $words[] = $this->dictionary->tripletTenSeparator();
35 | }
36 | }
37 |
38 | if (0 < $ten) {
39 | $words[] = $this->dictionary->getTripletTen($ten);
40 | }
41 |
42 | if (0 < $unit) {
43 | $words[] = $this->getTripletUnit($unit, $ten);
44 | }
45 |
46 | $words[] = $this->dictionary->getExponent($exponent);
47 |
48 | return $this->collapseWords($words);
49 | }
50 |
51 | /**
52 | * Chia 3 số thành mảng 3 phần tử tương ứng với hàng trăm, hàng chục, hàng đơn vị.
53 | *
54 | * @param int $triplet
55 | * @return array
56 | */
57 | private function splitTriplet(int $triplet): array
58 | {
59 | $hundred = (int) ($triplet / 100) % 10;
60 | $ten = (int) ($triplet / 10) % 10;
61 | $unit = $triplet % 10;
62 |
63 | return [$hundred, $ten, $unit];
64 | }
65 |
66 | /**
67 | * Chuyển đổi số hàng đơn vị sang chữ số ở một số trường hợp đặc biệt.
68 | *
69 | * @param int $unit
70 | * @param int $ten
71 | * @return null|string
72 | */
73 | private function getTripletUnit(int $unit, int $ten): string
74 | {
75 | if (1 <= $ten && 5 === $unit) {
76 | return $this->dictionary->specialTripletUnitFive();
77 | }
78 |
79 | if (2 <= $ten) {
80 | if (1 === $unit) {
81 | return $this->dictionary->specialTripletUnitOne();
82 | }
83 |
84 | if (4 === $unit) {
85 | return $this->dictionary->specialTripletUnitFour();
86 | }
87 | }
88 |
89 | return $this->dictionary->getTripletUnit($unit);
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/Concerns/TripletsConverter.php:
--------------------------------------------------------------------------------
1 |
13 | *
14 | * @since 1.0.0
15 | */
16 | trait TripletsConverter
17 | {
18 | /**
19 | * Chia số truyền vào thành các cụm gồm 3 số để hổ trợ cho việc chuyển sang chữ số.
20 | *
21 | * @param int $number
22 | * @return array|int[]
23 | */
24 | protected function numberToTriplets(int $number): array
25 | {
26 | $triplets = [];
27 |
28 | while (0 < $number) {
29 | array_unshift($triplets, $number % 1000);
30 | $number = (int) ($number / 1000);
31 | }
32 |
33 | return $triplets;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Dictionary.php:
--------------------------------------------------------------------------------
1 |
15 | *
16 | * @since 1.0.0
17 | */
18 | class Dictionary implements DictionaryInterface
19 | {
20 | /**
21 | * Mảng tập hợp hàng đơn vị.
22 | *
23 | * @var array
24 | */
25 | protected static $tripletUnits = [
26 | 'không',
27 | 'một',
28 | 'hai',
29 | 'ba',
30 | 'bốn',
31 | 'năm',
32 | 'sáu',
33 | 'bảy',
34 | 'tám',
35 | 'chín',
36 | ];
37 |
38 | /**
39 | * Mảng tập hợp hàng chục.
40 | *
41 | * @var array
42 | */
43 | protected static $tripletTens = [
44 | '',
45 | 'mười',
46 | 'hai mươi',
47 | 'ba mươi',
48 | 'bốn mươi',
49 | 'năm mươi',
50 | 'sáu mươi',
51 | 'bảy mươi',
52 | 'tám mươi',
53 | 'chín mươi',
54 | ];
55 |
56 | /**
57 | * Từ ngữ mô tả hàng trăm.
58 | *
59 | * @var string
60 | */
61 | protected static $hundred = 'trăm';
62 |
63 | /**
64 | * Mảng tập hợp đơn vị tính dựa trên số mũ 3.
65 | *
66 | * @var array
67 | */
68 | protected static $exponents = [
69 | '',
70 | 'nghìn',
71 | 'triệu',
72 | 'tỷ',
73 | 'nghìn tỷ',
74 | 'triệu tỷ',
75 | ];
76 |
77 | /**
78 | * {@inheritdoc}
79 | */
80 | public function zero(): string
81 | {
82 | return static::$tripletUnits[0];
83 | }
84 |
85 | /**
86 | * {@inheritdoc}
87 | */
88 | public function minus(): string
89 | {
90 | return 'âm';
91 | }
92 |
93 | /**
94 | * {@inheritdoc}
95 | */
96 | public function separator(): string
97 | {
98 | return ' ';
99 | }
100 |
101 | /**
102 | * {@inheritdoc}
103 | */
104 | public function tripletTenSeparator(): string
105 | {
106 | return 'linh';
107 | }
108 |
109 | /**
110 | * {@inheritdoc}
111 | */
112 | public function specialTripletUnitOne(): string
113 | {
114 | return 'mốt';
115 | }
116 |
117 | /**
118 | * {@inheritdoc}
119 | */
120 | public function specialTripletUnitFour(): string
121 | {
122 | return 'tư';
123 | }
124 |
125 | /**
126 | * {@inheritdoc}
127 | */
128 | public function specialTripletUnitFive(): string
129 | {
130 | return 'lăm';
131 | }
132 |
133 | /**
134 | * {@inheritdoc}
135 | */
136 | public function fraction(): string
137 | {
138 | return 'phẩy';
139 | }
140 |
141 | /**
142 | * {@inheritdoc}
143 | */
144 | public function getTripletUnit(int $unit): string
145 | {
146 | if (! isset(static::$tripletUnits[$unit])) {
147 | throw new InvalidArgumentException(sprintf('Unit arg (`%s`) must be in 0-9 range!', $unit));
148 | }
149 |
150 | return static::$tripletUnits[$unit];
151 | }
152 |
153 | /**
154 | * {@inheritdoc}
155 | */
156 | public function getTripletTen(int $ten): string
157 | {
158 | if (! isset(static::$tripletTens[$ten])) {
159 | throw new InvalidArgumentException(sprintf('Ten arg (`%s`) must be in 0-9 range!', $ten));
160 | }
161 |
162 | return static::$tripletTens[$ten];
163 | }
164 |
165 | /**
166 | * {@inheritdoc}
167 | */
168 | public function getTripletHundred(int $hundred): string
169 | {
170 | if (! isset(static::$tripletUnits[$hundred])) {
171 | throw new InvalidArgumentException(sprintf('Hundred arg (`%s`) must be in 0-9 range!', $hundred));
172 | }
173 |
174 | return static::$tripletUnits[$hundred].$this->separator().static::$hundred;
175 | }
176 |
177 | /**
178 | * {@inheritdoc}
179 | */
180 | public function getExponent(int $power): string
181 | {
182 | if (! isset(static::$exponents[$power])) {
183 | throw new InvalidArgumentException(sprintf('Power arg (`%s`) not exist in vietnamese dictionary!', $power));
184 | }
185 |
186 | return static::$exponents[$power];
187 | }
188 | }
189 |
--------------------------------------------------------------------------------
/src/DictionaryInterface.php:
--------------------------------------------------------------------------------
1 |
13 | *
14 | * @since 1.0.0
15 | */
16 | interface DictionaryInterface
17 | {
18 | /**
19 | * Trả về từ ngữ diễn giải số 0.
20 | *
21 | * @return string
22 | */
23 | public function zero(): string;
24 |
25 | /**
26 | * Trả về từ ngữ diễn giải số âm.
27 | *
28 | * @return string
29 | */
30 | public function minus(): string;
31 |
32 | /**
33 | * Trả về giá trị ngắt các chữ số.
34 | *
35 | * @return string
36 | */
37 | public function separator(): string;
38 |
39 | /**
40 | * Trả về từ ngữ ngắt giữa nguyên số và phân số.
41 | *
42 | * @return string
43 | */
44 | public function fraction(): string;
45 |
46 | /**
47 | * Trả về từ ngữ khi chuyển đổi 1 sang chữ số khi chữ số hàng chục lớn hơn 1.
48 | *
49 | * @return string
50 | */
51 | public function specialTripletUnitOne(): string;
52 |
53 | /**
54 | * Trả về từ ngữ khi chuyển đổi 4 sang chữ số khi chữ số hàng chục lớn hơn hoặc bằng 2.
55 | *
56 | * @return string
57 | */
58 | public function specialTripletUnitFour(): string;
59 |
60 | /**
61 | * Trả về từ ngữ khi chuyển đổi 5 sang chữ số khi chữ số hàng chục lớn hơn hoặc bằng 1.
62 | *
63 | * @return string
64 | */
65 | public function specialTripletUnitFive(): string;
66 |
67 | /**
68 | * Trả về từ ngữ nằm giữa hàng trăm và hàng đơn vị khi chữ số hàng chục là 0 và chữ số hàng trăm, đơn vị khác 0.
69 | *
70 | * @return string
71 | */
72 | public function tripletTenSeparator(): string;
73 |
74 | /**
75 | * Trả về từ ngữ hàng đơn vị tương ứng với số truyền vào.
76 | *
77 | * @param int $unit hàng đơn vị
78 | * @return string
79 | */
80 | public function getTripletUnit(int $unit): string;
81 |
82 | /**
83 | * Trả về từ ngữ hàng chục tương ứng với số truyền vào.
84 | *
85 | * @param int $ten hàng chục
86 | * @return string
87 | */
88 | public function getTripletTen(int $ten): string;
89 |
90 | /**
91 | * Trả về từ ngữ hàng trăm tương ứng với số truyền vào.
92 | *
93 | * @param int $hundred hàng trăm
94 | * @return string
95 | */
96 | public function getTripletHundred(int $hundred): string;
97 |
98 | /**
99 | * Trả về đơn vị tương ứng với số mũ cơ số 3.
100 | *
101 | * @param int $power hàng trăm
102 | * @return string
103 | */
104 | public function getExponent(int $power): string;
105 | }
106 |
--------------------------------------------------------------------------------
/src/SouthDictionary.php:
--------------------------------------------------------------------------------
1 |
13 | *
14 | * @since 1.0.0
15 | */
16 | class SouthDictionary extends Dictionary
17 | {
18 | /**
19 | * Thay nghìn => ngàn.
20 | *
21 | * @var array
22 | */
23 | protected static $exponents = [
24 | '',
25 | 'ngàn',
26 | 'triệu',
27 | 'tỷ',
28 | 'ngàn tỷ',
29 | 'triệu tỷ',
30 | ];
31 |
32 | /**
33 | * {@inheritdoc}
34 | */
35 | public function tripletTenSeparator(): string
36 | {
37 | return 'lẻ';
38 | }
39 |
40 | /**
41 | * {@inheritdoc}
42 | */
43 | public function specialTripletUnitFour(): string
44 | {
45 | return 'bốn';
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/Transformer.php:
--------------------------------------------------------------------------------
1 |
13 | *
14 | * @since 1.0.0
15 | */
16 | class Transformer
17 | {
18 | use Concerns\Collapse;
19 | use Concerns\NumberResolver;
20 | use Concerns\TripletsConverter;
21 | use Concerns\TripletTransformer;
22 |
23 | /**
24 | * @var DictionaryInterface
25 | */
26 | protected $dictionary;
27 |
28 | /**
29 | * Mặc định bỏ số các số 0 sau phần thập phân.
30 | *
31 | * @var int
32 | */
33 | protected $decimalPart;
34 |
35 | /**
36 | * Tạo đối tượng mới với từ điển chỉ định và phần thập phân.
37 | *
38 | * @param DictionaryInterface $dictionary
39 | */
40 | public function __construct(?DictionaryInterface $dictionary = null, $decimalPart = null)
41 | {
42 | if (null === $dictionary) {
43 | $dictionary = new Dictionary();
44 | }
45 |
46 | $this->dictionary = $dictionary;
47 | $this->decimalPart = $decimalPart;
48 | }
49 |
50 | /**
51 | * Chuyển đổi số sang chữ số.
52 | *
53 | * @param int|float|string $number
54 | * @return string
55 | *
56 | * @throws \InvalidArgumentException
57 | */
58 | public function toWords($number): string
59 | {
60 | [$minus, $number, $decimal] = $this->resolveNumber($number);
61 | $words[] = $minus ? $this->dictionary->minus() : '';
62 |
63 | if (0 === $number) {
64 | $words[] = $this->dictionary->zero();
65 | }
66 |
67 | $triplets = $this->numberToTriplets($number);
68 |
69 | foreach ($triplets as $pos => $triplet) {
70 | if (0 < $triplet) {
71 | $words[] = $this->tripletToWords($triplet, 0 === $pos, count($triplets) - $pos - 1);
72 | }
73 | }
74 |
75 | if (0 < $decimal) {
76 | $words[] = $this->dictionary->fraction();
77 | $words[] = $this->toWords($decimal);
78 | }
79 |
80 | return $this->collapseWords($words);
81 | }
82 |
83 | /**
84 | * Chuyển đổi số sang chữ số kết hợp với đơn vị tiền tệ.
85 | *
86 | * @param $number
87 | * @param array|string[]|string $unit
88 | * @return string
89 | *
90 | * @throws \InvalidArgumentException
91 | */
92 | public function toCurrency($number, $unit = 'đồng'): string
93 | {
94 | $unit = (array) $unit;
95 | $originNumber = $number;
96 | [$minus, $number, $decimal] = $this->resolveNumber($number);
97 |
98 | if (0 === $decimal || ! isset($unit[1])) {
99 | $words[] = $this->toWords($originNumber);
100 | $words[] = $unit[0];
101 | } else {
102 | [$unit, $decimalUnit] = $unit;
103 | $words[] = $minus ? $this->dictionary->minus() : '';
104 | $words[] = $this->toWords($number);
105 | $words[] = $unit;
106 | $words[] = $this->toWords($decimal);
107 | $words[] = $decimalUnit;
108 | }
109 |
110 | return $this->collapseWords($words);
111 | }
112 | }
113 |
--------------------------------------------------------------------------------