add chineseToNumber

This commit is contained in:
Looly 2021-03-10 17:44:52 +08:00
parent fc47566ddc
commit 5cdbd16c0b
8 changed files with 84 additions and 138 deletions

View File

@ -14,6 +14,7 @@
* 【core 】 增加StrMatcherissue#1379@Github * 【core 】 增加StrMatcherissue#1379@Github
* 【core 】 NumberUtil增加factorial针对BigInterger方法issue#1379@Github * 【core 】 NumberUtil增加factorial针对BigInterger方法issue#1379@Github
* 【core 】 TreeNode增加equals方法issue#1467@Github * 【core 】 TreeNode增加equals方法issue#1467@Github
* 【core 】 增加汉字转阿拉伯数字Convert.chineseToNumberpr#1469@Github
### Bug修复 ### Bug修复
* 【socket 】 修复Client创建失败资源未释放问题。 * 【socket 】 修复Client创建失败资源未释放问题。

View File

@ -1,52 +0,0 @@
package cn.hutool.core.convert;
/**
* @author totalo
* @since 5.6.0
* 中文转数字结构
*/
public final class ChineseNameValue {
/**
* 中文权名称
*/
String name;
/**
* 10的倍数值
*/
int value;
/**
* 是否为节权位
*/
boolean secUnit;
public ChineseNameValue(String name, int value, boolean secUnit) {
this.name = name;
this.value = value;
this.secUnit = secUnit;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public boolean isSecUnit() {
return secUnit;
}
public void setSecUnit(boolean secUnit) {
this.secUnit = secUnit;
}
}

View File

@ -982,12 +982,27 @@ public class Convert {
* 将阿拉伯数字转为中文表达方式 * 将阿拉伯数字转为中文表达方式
* *
* @param number 数字 * @param number 数字
* @param isUseTraditonal 是否使用繁体字金额形式 * @param isUseTraditional 是否使用繁体字金额形式
* @return 中文 * @return 中文
* @since 3.2.3 * @since 3.2.3
*/ */
public static String numberToChinese(double number, boolean isUseTraditonal) { public static String numberToChinese(double number, boolean isUseTraditional) {
return NumberChineseFormatter.format(number, isUseTraditonal); return NumberChineseFormatter.format(number, isUseTraditional);
}
/**
* 数字中文表示形式转数字
* <ul>
* <li>一百一十二 - 112</li>
* <li>一千零一十二 - 1012</li>
* </ul>
*
* @param number 数字中文表示
* @return 数字
* @since 5.6.0
*/
public static int chineseToNumber(String number){
return NumberChineseFormatter.chineseToNumber(number);
} }
/** /**

View File

@ -1,17 +0,0 @@
package cn.hutool.core.convert;
/**
* 数字转中文类<br>
* 包括
* <pre>
* 1. 数字转中文大写形式比如一百二十一
* 2. 数字转金额用的大写形式比如壹佰贰拾壹
* 3. 转金额形式比如壹佰贰拾壹整
* </pre>
*
* @author fanqun, looly
* @deprecated 请使用 {@link NumberChineseFormatter}
**/
@Deprecated
public class NumberChineseFormater extends NumberChineseFormatter{
}

View File

@ -1,5 +1,6 @@
package cn.hutool.core.convert; package cn.hutool.core.convert;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
/** /**
@ -178,10 +179,6 @@ public class NumberChineseFormatter {
* @return 转换后的汉字 * @return 转换后的汉字
*/ */
private static String toChinese(int amountPart, boolean isUseTraditional) { private static String toChinese(int amountPart, boolean isUseTraditional) {
// if (amountPart < 0 || amountPart > 10000) {
// throw new IllegalArgumentException("Number must 0 < num < 10000");
// }
String[] numArray = isUseTraditional ? TRADITIONAL_DIGITS : SIMPLE_DIGITS; String[] numArray = isUseTraditional ? TRADITIONAL_DIGITS : SIMPLE_DIGITS;
String[] units = isUseTraditional ? TRADITIONAL_UNITS : SIMPLE_UNITS; String[] units = isUseTraditional ? TRADITIONAL_UNITS : SIMPLE_UNITS;
@ -207,10 +204,16 @@ public class NumberChineseFormatter {
} }
/** /**
* 把中文转换为数字 二百二 220 * 把中文转换为数字 二百二 220<br>
* @see <url>https://www.d5.nz/read/sfdlq/text-part0000_split_030.html</url> * https://www.d5.nz/read/sfdlq/text-part0000_split_030.html
* <ul>
* <li>一百一十二 - 112</li>
* <li>一千零一十二 - 1012</li>
* </ul>
*
* @param chinese 中文字符 * @param chinese 中文字符
* @return * @return 数字
* @since 5.6.0
*/ */
public static int chineseToNumber(String chinese) { public static int chineseToNumber(String chinese) {
int pos = 0; int pos = 0;
@ -218,12 +221,13 @@ public class NumberChineseFormatter {
int section = 0; int section = 0;
int number = 0; int number = 0;
boolean secUnit = false; boolean secUnit = false;
while (pos < chinese.length()) { final int length = chinese.length();
int num = chineseToValue(chinese.substring(pos, pos + 1)); while (pos < length) {
int num = ArrayUtil.indexOf(SIMPLE_DIGITS, chinese.substring(pos, pos + 1));
if (num >= 0) { if (num >= 0) {
number = num; number = num;
pos += 1; pos += 1;
if (pos >= chinese.length()) { if (pos >= length) {
section += number; section += number;
rtn += section; rtn += section;
break; break;
@ -232,8 +236,8 @@ public class NumberChineseFormatter {
int unit = 1; int unit = 1;
int tmp = chineseToUnit(chinese.substring(pos, pos + 1)); int tmp = chineseToUnit(chinese.substring(pos, pos + 1));
if (tmp != -1) { if (tmp != -1) {
unit = CHINESE_NAME_VALUE[tmp].getValue(); unit = CHINESE_NAME_VALUE[tmp].value;
secUnit = CHINESE_NAME_VALUE[tmp].isSecUnit(); secUnit = CHINESE_NAME_VALUE[tmp].secUnit;
} }
if (secUnit) { if (secUnit) {
section = (section + number) * unit; section = (section + number) * unit;
@ -254,13 +258,14 @@ public class NumberChineseFormatter {
} }
/** /**
* 中文到数字的转换 * 查找对应的权
* @param chinese *
* @return * @param chinese 中文权位名
* @return 位置
*/ */
private static int chineseToValue(String chinese) { private static int chineseToUnit(String chinese) {
for (int i = 0; i < SIMPLE_DIGITS.length; i++) { for (int i = 0; i < CHINESE_NAME_VALUE.length; i++) {
if (SIMPLE_DIGITS[i].equals(chinese)) { if (CHINESE_NAME_VALUE[i].name.equals(chinese)) {
return i; return i;
} }
} }
@ -268,16 +273,29 @@ public class NumberChineseFormatter {
} }
/** /**
* 查找对应的权 * 权位
* @param chinese *
* @return * @author totalo
* @since 5.6.0
*/ */
private static int chineseToUnit(String chinese) { private static class ChineseNameValue {
for (int i = 0; i < CHINESE_NAME_VALUE.length; i++) { /**
if (CHINESE_NAME_VALUE[i].getName().equals(chinese)) { * 中文权名称
return i; */
private final String name;
/**
* 10的倍数值
*/
private final int value;
/**
* 是否为节权位
*/
private final boolean secUnit;
public ChineseNameValue(String name, int value, boolean secUnit) {
this.name = name;
this.value = value;
this.secUnit = secUnit;
} }
} }
return -1;
}
} }

View File

@ -1,14 +0,0 @@
package cn.hutool.core.convert;
/**
* 将浮点数类型的number转换成英语的表达方式 <br>
* 参考博客http://blog.csdn.net/eric_sunah/article/details/8713226
*
* @author Looly
* @since 3.0.9
* @deprecated 请使用 {@link NumberWordFormatter}
*/
@Deprecated
public class NumberWordFormater extends NumberWordFormatter{
}

View File

@ -83,15 +83,10 @@ public class NumberChineseFormatterTest {
@Test @Test
public void chineseToNumberTest(){ public void chineseToNumberTest(){
Assert.assertEquals(0, NumberChineseFormatter.chineseToNumber("")); Assert.assertEquals(0, NumberChineseFormatter.chineseToNumber(""));
Assert.assertEquals(102, NumberChineseFormatter.chineseToNumber("一百零二")); Assert.assertEquals(102, NumberChineseFormatter.chineseToNumber("一百零二"));
Assert.assertEquals(112, NumberChineseFormatter.chineseToNumber("一百一十二")); Assert.assertEquals(112, NumberChineseFormatter.chineseToNumber("一百一十二"));
Assert.assertEquals(1012, NumberChineseFormatter.chineseToNumber("一千零一十二")); Assert.assertEquals(1012, NumberChineseFormatter.chineseToNumber("一千零一十二"));
Assert.assertEquals(1000000, NumberChineseFormatter.chineseToNumber("一百万")); Assert.assertEquals(1000000, NumberChineseFormatter.chineseToNumber("一百万"));
Assert.assertEquals(2000100112, NumberChineseFormatter.chineseToNumber("二十亿零一十万零一百一十二")); Assert.assertEquals(2000100112, NumberChineseFormatter.chineseToNumber("二十亿零一十万零一百一十二"));
} }
} }

View File

@ -55,7 +55,7 @@ public class CronUtil {
* 设置是否支持秒匹配<br> * 设置是否支持秒匹配<br>
* 此方法用于定义是否使用秒匹配模式如果为true则定时任务表达式中的第一位为秒否则为分默认是分<br> * 此方法用于定义是否使用秒匹配模式如果为true则定时任务表达式中的第一位为秒否则为分默认是分<br>
* *
* @param isMatchSecond <code>true</code>支持<code>false</code>不支持 * @param isMatchSecond {@code true}支持{@code false}不支持
*/ */
public static void setMatchSecond(boolean isMatchSecond) { public static void setMatchSecond(boolean isMatchSecond) {
scheduler.setMatchSecond(isMatchSecond); scheduler.setMatchSecond(isMatchSecond);