This commit is contained in:
Looly
2024-04-21 10:02:07 +08:00
parent dfdb62d6b0
commit da0e7ae338
6 changed files with 336 additions and 294 deletions

View File

@@ -20,7 +20,8 @@ import org.dromara.hutool.core.convert.impl.EnumConverter;
import org.dromara.hutool.core.convert.impl.MapConverter;
import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.core.math.ChineseNumberFormatter;
import org.dromara.hutool.core.math.NumberWordFormatter;
import org.dromara.hutool.core.math.ChineseNumberParser;
import org.dromara.hutool.core.math.EnglishNumberFormatter;
import org.dromara.hutool.core.reflect.TypeReference;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.text.UnicodeUtil;
@@ -1003,7 +1004,7 @@ public class Convert {
* @since 3.0.9
*/
public static String numberToWord(final Number number) {
return NumberWordFormatter.format(number);
return EnglishNumberFormatter.format(number);
}
/**
@@ -1018,7 +1019,7 @@ public class Convert {
* @since 5.5.9
*/
public static String numberToSimple(final Number number) {
return NumberWordFormatter.formatSimple(number.longValue());
return EnglishNumberFormatter.formatSimple(number.longValue());
}
/**
@@ -1047,7 +1048,7 @@ public class Convert {
* @since 5.6.0
*/
public static int chineseToNumber(final String number){
return ChineseNumberFormatter.parseFromChinese(number);
return ChineseNumberParser.parseFromChineseNumber(number);
}
/**
@@ -1078,7 +1079,7 @@ public class Convert {
* @since 5.8.5
*/
public static BigDecimal chineseMoneyToNumber(final String chineseMoneyAmount){
return ChineseNumberFormatter.parseFromChineseMoney(chineseMoneyAmount);
return ChineseNumberParser.parseFromChineseMoney(chineseMoneyAmount);
}
// -------------------------------------------------------------------------- 数字转换

View File

@@ -14,10 +14,6 @@ package org.dromara.hutool.core.math;
import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.array.ArrayUtil;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
* 数字转中文类<br>
@@ -68,155 +64,6 @@ public class ChineseNumberFormatter {
return numberToChinese(c - '0', isUseTraditional);
}
/**
* 把中文转换为数字 如 二百二十 220<br>
* <ul>
* <li>一百一十二 -》 112</li>
* <li>一千零一十二 -》 1012</li>
* </ul>
*
* @param chinese 中文字符
* @return 数字
* @since 5.6.0
*/
public static int parseFromChinese(final String chinese) {
final int length = chinese.length();
int result = 0;
// 节总和
int section = 0;
int number = 0;
ChineseUnit unit = null;
char c;
for (int i = 0; i < length; i++) {
c = chinese.charAt(i);
final int num = parseFromChinese(c);
if (num >= 0) {
if (num == 0) {
// 遇到零时节结束,权位失效,比如两万二零一十
if (number > 0 && null != unit) {
section += number * (unit.value / 10);
}
unit = null;
} else if (number > 0) {
// 多个数字同时出现,报错
throw new IllegalArgumentException(StrUtil.format("Bad number '{}{}' at: {}", chinese.charAt(i - 1), c, i));
}
// 普通数字
number = num;
} else {
unit = chineseToUnit(c);
if (null == unit) {
// 出现非法字符
throw new IllegalArgumentException(StrUtil.format("Unknown unit '{}' at: {}", c, i));
}
//单位
if (unit.secUnit) {
// 节单位,按照节求和
section = (section + number) * unit.value;
result += section;
section = 0;
} else {
// 非节单位,和单位前的单数字组合为值
int unitNumber = number;
if (0 == number && 0 == i) {
// issue#1726对于单位开头的数组默认赋予1
// 十二 -> 一十二
// 百二 -> 一百二
unitNumber = 1;
}
section += (unitNumber * unit.value);
}
number = 0;
}
}
if (number > 0 && null != unit) {
number = number * (unit.value / 10);
}
return result + section + number;
}
/**
* 中文大写数字金额转换为数字返回结果以元为单位的BigDecimal类型数字<br>
* 如:
* “陆万柒仟伍佰伍拾陆元叁角贰分”返回“67556.32”
* “叁角贰分”返回“0.32”
*
* @param chineseMoneyAmount 中文大写数字金额
* @return 返回结果以元为单位的BigDecimal类型数字
*/
public static BigDecimal parseFromChineseMoney(final String chineseMoneyAmount) {
if (StrUtil.isBlank(chineseMoneyAmount)) {
return null;
}
int yi = chineseMoneyAmount.indexOf("");
if (yi == -1) {
yi = chineseMoneyAmount.indexOf("");
}
final int ji = chineseMoneyAmount.indexOf("");
final int fi = chineseMoneyAmount.indexOf("");
// 先找到单位为元的数字
String yStr = null;
if (yi > 0) {
yStr = chineseMoneyAmount.substring(0, yi);
}
// 再找到单位为角的数字
String jStr = null;
if (ji > 0) {
if (yi >= 0) {
//前面有元,角肯定要在元后面
if (ji > yi) {
jStr = chineseMoneyAmount.substring(yi + 1, ji);
}
} else {
//没有元,只有角
jStr = chineseMoneyAmount.substring(0, ji);
}
}
// 再找到单位为分的数字
String fStr = null;
if (fi > 0) {
if (ji >= 0) {
//有角,分肯定在角后面
if (fi > ji) {
fStr = chineseMoneyAmount.substring(ji + 1, fi);
}
} else if (yi > 0) {
//没有角,有元,那就坐元后面找
if (fi > yi) {
fStr = chineseMoneyAmount.substring(yi + 1, fi);
}
} else {
//没有元、角,只有分
fStr = chineseMoneyAmount.substring(0, fi);
}
}
//元、角、分
int y = 0, j = 0, f = 0;
if (StrUtil.isNotBlank(yStr)) {
y = ChineseNumberFormatter.parseFromChinese(yStr);
}
if (StrUtil.isNotBlank(jStr)) {
j = ChineseNumberFormatter.parseFromChinese(jStr);
}
if (StrUtil.isNotBlank(fStr)) {
f = ChineseNumberFormatter.parseFromChinese(fStr);
}
BigDecimal amount = new BigDecimal(y);
amount = amount.add(BigDecimal.valueOf(j).divide(BigDecimal.TEN, 2, RoundingMode.HALF_UP));
amount = amount.add(BigDecimal.valueOf(f).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP));
return amount;
}
/**
* 获取 NumberChineseFormatter 默认对象
*
@@ -230,24 +77,9 @@ public class ChineseNumberFormatter {
* 中文形式奇数位置是简体偶数位置是记账繁体0共用<br>
* 使用混合数组提高效率和数组复用
**/
private static final char[] DIGITS = {'零', '一', '壹', '二', '贰', '三', '叁', '四', '肆', '五', '伍',
static final char[] DIGITS = {'零', '一', '壹', '二', '贰', '三', '叁', '四', '肆', '五', '伍',
'六', '陆', '七', '柒', '八', '捌', '九', '玖'};
/**
* 汉字转阿拉伯数字的
*/
private static final ChineseUnit[] CHINESE_NAME_VALUE = {
new ChineseUnit(' ', 1, false),
new ChineseUnit('十', 10, false),
new ChineseUnit('拾', 10, false),
new ChineseUnit('百', 100, false),
new ChineseUnit('佰', 100, false),
new ChineseUnit('千', 1000, false),
new ChineseUnit('仟', 1000, false),
new ChineseUnit('万', 1_0000, true),
new ChineseUnit('亿', 1_0000_0000, true),
};
// region ----- 配置项
private boolean useTraditional;
private boolean moneyMode;
@@ -514,7 +346,7 @@ public class ChineseNumberFormatter {
lastIsZero = true;
} else { // 取到的数字不是 0
final boolean isUseTraditional = this.useTraditional;
chineseStr.insert(0, numberToChinese(digit, isUseTraditional) + getUnitName(i, isUseTraditional));
chineseStr.insert(0, numberToChinese(digit, isUseTraditional) + ChineseNumberParser.getUnitName(i, isUseTraditional));
lastIsZero = false;
}
temp = temp / 10;
@@ -522,40 +354,6 @@ public class ChineseNumberFormatter {
return chineseStr.toString();
}
/**
* 查找对应的权对象
*
* @param chinese 中文权位名
* @return 权对象
*/
private static ChineseUnit chineseToUnit(final char chinese) {
for (final ChineseUnit chineseNameValue : CHINESE_NAME_VALUE) {
if (chineseNameValue.name == chinese) {
return chineseNameValue;
}
}
return null;
}
/**
* 将汉字单个数字转换为int类型数字
*
* @param chinese 汉字数字,支持简体和繁体
* @return 数字,-1表示未找到
* @since 5.6.4
*/
private static int parseFromChinese(char chinese) {
if ('两' == chinese) {
// 口语纠正
chinese = '二';
}
final int i = ArrayUtil.indexOf(DIGITS, chinese);
if (i > 0) {
return (i + 1) / 2;
}
return i;
}
/**
* 单个数字转汉字
*
@@ -570,20 +368,6 @@ public class ChineseNumberFormatter {
return DIGITS[number * 2 - (isUseTraditional ? 0 : 1)];
}
/**
* 获取对应级别的单位
*
* @param index 级别0表示各位1表示十位2表示百位以此类推
* @param isUseTraditional 是否使用繁体
* @return 单位
*/
private static String getUnitName(final int index, final boolean isUseTraditional) {
if (0 == index) {
return StrUtil.EMPTY;
}
return String.valueOf(CHINESE_NAME_VALUE[index * 2 - (isUseTraditional ? 0 : 1)].name);
}
private static void addPreZero(final StringBuilder chineseStr) {
if (StrUtil.isEmpty(chineseStr)) {
return;
@@ -592,39 +376,4 @@ public class ChineseNumberFormatter {
chineseStr.insert(0, '零');
}
}
/**
* 权位
*
* @author totalo
* @since 5.6.0
*/
private static class ChineseUnit {
/**
* 中文权名称
*/
private final char name;
/**
* 10的倍数值
*/
private final int value;
/**
* 是否为节权位,它不是与之相邻的数字的倍数,而是整个小节的倍数。<br>
* 例如二十三万,万是节权位,与三无关,而和二十三关联
*/
private final boolean secUnit;
/**
* 构造
*
* @param name 名称
* @param value 值即10的倍数
* @param secUnit 是否为节权位
*/
public ChineseUnit(final char name, final int value, final boolean secUnit) {
this.name = name;
this.value = value;
this.secUnit = secUnit;
}
}
}

View File

@@ -0,0 +1,294 @@
/*
* Copyright (c) 2024. looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* https://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.core.math;
import org.dromara.hutool.core.array.ArrayUtil;
import org.dromara.hutool.core.text.StrUtil;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
* 中文数字或金额解析类
*
* @author fanqun, looly
* @since 6.0.0
*/
public class ChineseNumberParser {
/**
* 汉字转阿拉伯数字的
*/
private static final ChineseUnit[] CHINESE_NAME_VALUE = {
new ChineseUnit(' ', 1, false),
new ChineseUnit('十', 10, false),
new ChineseUnit('拾', 10, false),
new ChineseUnit('百', 100, false),
new ChineseUnit('佰', 100, false),
new ChineseUnit('千', 1000, false),
new ChineseUnit('仟', 1000, false),
new ChineseUnit('万', 1_0000, true),
new ChineseUnit('亿', 1_0000_0000, true),
};
/**
* 把中文转换为数字 如 二百二十 -》 220<br>
* <ul>
* <li>一百一十二 -》 112</li>
* <li>一千零一十二 -》 1012</li>
* </ul>
*
* @param chinese 中文字符
* @return 数字
* @since 5.6.0
*/
public static Number parseFromChinese(final String chinese) {
if(StrUtil.containsAny(chinese, '元', '圆', '角', '分')){
return parseFromChineseMoney(chinese);
}
return parseFromChineseNumber(chinese);
}
/**
* 把中文转换为数字 如 二百二十 220<br>
* <ul>
* <li>一百一十二 -》 112</li>
* <li>一千零一十二 -》 1012</li>
* </ul>
*
* @param chinese 中文字符
* @return 数字
* @since 5.6.0
*/
public static int parseFromChineseNumber(final String chinese) {
final int length = chinese.length();
int result = 0;
// 节总和
int section = 0;
int number = 0;
ChineseUnit unit = null;
char c;
for (int i = 0; i < length; i++) {
c = chinese.charAt(i);
final int num = chineseToNumber(c);
if (num >= 0) {
if (num == 0) {
// 遇到零时节结束,权位失效,比如两万二零一十
if (number > 0 && null != unit) {
section += number * (unit.value / 10);
}
unit = null;
} else if (number > 0) {
// 多个数字同时出现,报错
throw new IllegalArgumentException(StrUtil.format("Bad number '{}{}' at: {}", chinese.charAt(i - 1), c, i));
}
// 普通数字
number = num;
} else {
unit = chineseToUnit(c);
if (null == unit) {
// 出现非法字符
throw new IllegalArgumentException(StrUtil.format("Unknown unit '{}' at: {}", c, i));
}
//单位
if (unit.secUnit) {
// 节单位,按照节求和
section = (section + number) * unit.value;
result += section;
section = 0;
} else {
// 非节单位,和单位前的单数字组合为值
int unitNumber = number;
if (0 == number && 0 == i) {
// issue#1726对于单位开头的数组默认赋予1
// 十二 -> 一十二
// 百二 -> 一百二
unitNumber = 1;
}
section += (unitNumber * unit.value);
}
number = 0;
}
}
if (number > 0 && null != unit) {
number = number * (unit.value / 10);
}
return result + section + number;
}
/**
* 中文大写数字金额转换为数字返回结果以元为单位的BigDecimal类型数字<br>
* 如:
* “陆万柒仟伍佰伍拾陆元叁角贰分”返回“67556.32”
* “叁角贰分”返回“0.32”
*
* @param chineseMoneyAmount 中文大写数字金额
* @return 返回结果以元为单位的BigDecimal类型数字
*/
public static BigDecimal parseFromChineseMoney(final String chineseMoneyAmount) {
if (StrUtil.isBlank(chineseMoneyAmount)) {
return null;
}
int yi = chineseMoneyAmount.indexOf("");
if (yi == -1) {
yi = chineseMoneyAmount.indexOf("");
}
final int ji = chineseMoneyAmount.indexOf("");
final int fi = chineseMoneyAmount.indexOf("");
// 先找到单位为元的数字
String yStr = null;
if (yi > 0) {
yStr = chineseMoneyAmount.substring(0, yi);
}
// 再找到单位为角的数字
String jStr = null;
if (ji > 0) {
if (yi >= 0) {
//前面有元,角肯定要在元后面
if (ji > yi) {
jStr = chineseMoneyAmount.substring(yi + 1, ji);
}
} else {
//没有元,只有角
jStr = chineseMoneyAmount.substring(0, ji);
}
}
// 再找到单位为分的数字
String fStr = null;
if (fi > 0) {
if (ji >= 0) {
//有角,分肯定在角后面
if (fi > ji) {
fStr = chineseMoneyAmount.substring(ji + 1, fi);
}
} else if (yi > 0) {
//没有角,有元,那就坐元后面找
if (fi > yi) {
fStr = chineseMoneyAmount.substring(yi + 1, fi);
}
} else {
//没有元、角,只有分
fStr = chineseMoneyAmount.substring(0, fi);
}
}
//元、角、分
int y = 0, j = 0, f = 0;
if (StrUtil.isNotBlank(yStr)) {
y = parseFromChineseNumber(yStr);
}
if (StrUtil.isNotBlank(jStr)) {
j = parseFromChineseNumber(jStr);
}
if (StrUtil.isNotBlank(fStr)) {
f = parseFromChineseNumber(fStr);
}
BigDecimal amount = new BigDecimal(y);
amount = amount.add(BigDecimal.valueOf(j).divide(BigDecimal.TEN, 2, RoundingMode.HALF_UP));
amount = amount.add(BigDecimal.valueOf(f).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP));
return amount;
}
/**
* 查找对应的权对象
*
* @param chinese 中文权位名
* @return 权对象
*/
private static ChineseUnit chineseToUnit(final char chinese) {
for (final ChineseUnit chineseNameValue : CHINESE_NAME_VALUE) {
if (chineseNameValue.name == chinese) {
return chineseNameValue;
}
}
return null;
}
/**
* 将汉字单个数字转换为int类型数字
*
* @param chinese 汉字数字,支持简体和繁体
* @return 数字,-1表示未找到
* @since 5.6.4
*/
private static int chineseToNumber(char chinese) {
if ('两' == chinese) {
// 口语纠正
chinese = '二';
}
final int i = ArrayUtil.indexOf(ChineseNumberFormatter.DIGITS, chinese);
if (i > 0) {
return (i + 1) / 2;
}
return i;
}
/**
* 获取对应级别的单位
*
* @param index 级别0表示各位1表示十位2表示百位以此类推
* @param isUseTraditional 是否使用繁体
* @return 单位
*/
static String getUnitName(final int index, final boolean isUseTraditional) {
if (0 == index) {
return StrUtil.EMPTY;
}
return String.valueOf(CHINESE_NAME_VALUE[index * 2 - (isUseTraditional ? 0 : 1)].name);
}
/**
* 权位
*
* @author totalo
* @since 5.6.0
*/
private static class ChineseUnit {
/**
* 中文权名称
*/
private final char name;
/**
* 10的倍数值
*/
private final int value;
/**
* 是否为节权位,它不是与之相邻的数字的倍数,而是整个小节的倍数。<br>
* 例如二十三万,万是节权位,与三无关,而和二十三关联
*/
private final boolean secUnit;
/**
* 构造
*
* @param name 名称
* @param value 值即10的倍数
* @param secUnit 是否为节权位
*/
public ChineseUnit(final char name, final int value, final boolean secUnit) {
this.name = name;
this.value = value;
this.secUnit = secUnit;
}
}
}

View File

@@ -12,7 +12,6 @@
package org.dromara.hutool.core.math;
import org.dromara.hutool.core.math.NumberUtil;
import org.dromara.hutool.core.text.StrUtil;
/**
@@ -22,7 +21,7 @@ import org.dromara.hutool.core.text.StrUtil;
* @author Looly, totalo
* @since 3.0.9
*/
public class NumberWordFormatter {
public class EnglishNumberFormatter {
private static final String[] NUMBER = new String[]{"", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN",
"EIGHT", "NINE"};

View File

@@ -283,21 +283,21 @@ public class NumberChineseFormatterTest {
@Test
public void chineseToNumberTest(){
Assertions.assertEquals(0, ChineseNumberFormatter.parseFromChinese(""));
Assertions.assertEquals(102, ChineseNumberFormatter.parseFromChinese("一百零二"));
Assertions.assertEquals(112, ChineseNumberFormatter.parseFromChinese("一百一十二"));
Assertions.assertEquals(1012, ChineseNumberFormatter.parseFromChinese("一千零一十二"));
Assertions.assertEquals(1000000, ChineseNumberFormatter.parseFromChinese("一百万"));
Assertions.assertEquals(2000100112, ChineseNumberFormatter.parseFromChinese("二十亿零一十万零一百一十二"));
Assertions.assertEquals(0, ChineseNumberParser.parseFromChinese(""));
Assertions.assertEquals(102, ChineseNumberParser.parseFromChinese("一百零二"));
Assertions.assertEquals(112, ChineseNumberParser.parseFromChinese("一百一十二"));
Assertions.assertEquals(1012, ChineseNumberParser.parseFromChinese("一千零一十二"));
Assertions.assertEquals(1000000, ChineseNumberParser.parseFromChinese("一百万"));
Assertions.assertEquals(2000100112, ChineseNumberParser.parseFromChinese("二十亿零一十万零一百一十二"));
}
@Test
public void chineseToNumberTest2(){
Assertions.assertEquals(120, ChineseNumberFormatter.parseFromChinese("一百二"));
Assertions.assertEquals(1200, ChineseNumberFormatter.parseFromChinese("一千二"));
Assertions.assertEquals(22000, ChineseNumberFormatter.parseFromChinese("两万二"));
Assertions.assertEquals(22003, ChineseNumberFormatter.parseFromChinese("两万二零三"));
Assertions.assertEquals(22010, ChineseNumberFormatter.parseFromChinese("两万二零一十"));
Assertions.assertEquals(120, ChineseNumberParser.parseFromChinese("一百二"));
Assertions.assertEquals(1200, ChineseNumberParser.parseFromChinese("一千二"));
Assertions.assertEquals(22000, ChineseNumberParser.parseFromChinese("两万二"));
Assertions.assertEquals(22003, ChineseNumberParser.parseFromChinese("两万二零三"));
Assertions.assertEquals(22010, ChineseNumberParser.parseFromChinese("两万二零一十"));
}
@Test
@@ -305,16 +305,16 @@ public class NumberChineseFormatterTest {
// issue#1726对于单位开头的数组默认赋予1
// 十二 -> 一十二
// 百二 -> 一百二
Assertions.assertEquals(12, ChineseNumberFormatter.parseFromChinese("十二"));
Assertions.assertEquals(120, ChineseNumberFormatter.parseFromChinese("百二"));
Assertions.assertEquals(1300, ChineseNumberFormatter.parseFromChinese("千三"));
Assertions.assertEquals(12, ChineseNumberParser.parseFromChinese("十二"));
Assertions.assertEquals(120, ChineseNumberParser.parseFromChinese("百二"));
Assertions.assertEquals(1300, ChineseNumberParser.parseFromChinese("千三"));
}
@Test
public void badNumberTest(){
Assertions.assertThrows(IllegalArgumentException.class, ()->{
// 连续数字检查
ChineseNumberFormatter.parseFromChinese("一百一二三");
ChineseNumberParser.parseFromChinese("一百一二三");
});
}
@@ -322,7 +322,7 @@ public class NumberChineseFormatterTest {
public void badNumberTest2(){
Assertions.assertThrows(IllegalArgumentException.class, ()->{
// 非法字符
ChineseNumberFormatter.parseFromChinese("一百你三");
ChineseNumberParser.parseFromChinese("一百你三");
});
}
@@ -373,13 +373,13 @@ public class NumberChineseFormatterTest {
* s=叁角贰分, n=0.32
* s=陆万柒仟伍佰伍拾陆元叁角贰分, n=67556.32
*/
Assertions.assertEquals(67556, ChineseNumberFormatter.parseFromChineseMoney("陆万柒仟伍佰伍拾陆圆").longValue());
Assertions.assertEquals(67556, ChineseNumberFormatter.parseFromChineseMoney("陆万柒仟伍佰伍拾陆元").longValue());
Assertions.assertEquals(0.3D, ChineseNumberFormatter.parseFromChineseMoney("叁角").doubleValue(), 0);
Assertions.assertEquals(0.02, ChineseNumberFormatter.parseFromChineseMoney("贰分").doubleValue(), 0);
Assertions.assertEquals(67556.3, ChineseNumberFormatter.parseFromChineseMoney("陆万柒仟伍佰伍拾陆元叁角").doubleValue(), 0);
Assertions.assertEquals(67556.02, ChineseNumberFormatter.parseFromChineseMoney("陆万柒仟伍佰伍拾陆元贰分").doubleValue(), 0);
Assertions.assertEquals(0.32, ChineseNumberFormatter.parseFromChineseMoney("叁角贰分").doubleValue(), 0);
Assertions.assertEquals(67556.32, ChineseNumberFormatter.parseFromChineseMoney("陆万柒仟伍佰伍拾陆元叁角贰分").doubleValue(), 0);
Assertions.assertEquals(67556, ChineseNumberParser.parseFromChineseMoney("陆万柒仟伍佰伍拾陆圆").longValue());
Assertions.assertEquals(67556, ChineseNumberParser.parseFromChineseMoney("陆万柒仟伍佰伍拾陆元").longValue());
Assertions.assertEquals(0.3D, ChineseNumberParser.parseFromChineseMoney("叁角").doubleValue(), 0);
Assertions.assertEquals(0.02, ChineseNumberParser.parseFromChineseMoney("贰分").doubleValue(), 0);
Assertions.assertEquals(67556.3, ChineseNumberParser.parseFromChineseMoney("陆万柒仟伍佰伍拾陆元叁角").doubleValue(), 0);
Assertions.assertEquals(67556.02, ChineseNumberParser.parseFromChineseMoney("陆万柒仟伍佰伍拾陆元贰分").doubleValue(), 0);
Assertions.assertEquals(0.32, ChineseNumberParser.parseFromChineseMoney("叁角贰分").doubleValue(), 0);
Assertions.assertEquals(67556.32, ChineseNumberParser.parseFromChineseMoney("陆万柒仟伍佰伍拾陆元叁角贰分").doubleValue(), 0);
}
}

View File

@@ -12,7 +12,6 @@
package org.dromara.hutool.core.math;
import org.dromara.hutool.core.math.NumberWordFormatter;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -20,37 +19,37 @@ public class NumberWordFormatTest {
@Test
public void formatTest() {
final String format = NumberWordFormatter.format(100.23);
final String format = EnglishNumberFormatter.format(100.23);
Assertions.assertEquals("ONE HUNDRED AND CENTS TWENTY THREE ONLY", format);
final String format2 = NumberWordFormatter.format("2100.00");
final String format2 = EnglishNumberFormatter.format("2100.00");
Assertions.assertEquals("TWO THOUSAND ONE HUNDRED AND CENTS ONLY", format2);
final String format3 = NumberWordFormatter.format("1234567890123.12");
final String format3 = EnglishNumberFormatter.format("1234567890123.12");
Assertions.assertEquals("ONE TRILLION TWO HUNDRED AND THIRTY FOUR BILLION FIVE HUNDRED AND SIXTY SEVEN MILLION EIGHT HUNDRED AND NINETY THOUSAND ONE HUNDRED AND TWENTY THREE AND CENTS TWELVE ONLY", format3);
}
@Test
public void formatSimpleTest() {
final String format1 = NumberWordFormatter.formatSimple(1200, false);
final String format1 = EnglishNumberFormatter.formatSimple(1200, false);
Assertions.assertEquals("1.2k", format1);
final String format2 = NumberWordFormatter.formatSimple(4384324, false);
final String format2 = EnglishNumberFormatter.formatSimple(4384324, false);
Assertions.assertEquals("4.38m", format2);
final String format3 = NumberWordFormatter.formatSimple(4384324, true);
final String format3 = EnglishNumberFormatter.formatSimple(4384324, true);
Assertions.assertEquals("438.43w", format3);
final String format4 = NumberWordFormatter.formatSimple(4384324);
final String format4 = EnglishNumberFormatter.formatSimple(4384324);
Assertions.assertEquals("438.43w", format4);
final String format5 = NumberWordFormatter.formatSimple(438);
final String format5 = EnglishNumberFormatter.formatSimple(438);
Assertions.assertEquals("438", format5);
}
@Test
public void formatSimpleTest2(){
final String s = NumberWordFormatter.formatSimple(1000);
final String s = EnglishNumberFormatter.formatSimple(1000);
Assertions.assertEquals("1k", s);
}
}