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 】 NumberUtil增加factorial针对BigInterger方法issue#1379@Github
* 【core 】 TreeNode增加equals方法issue#1467@Github
* 【core 】 增加汉字转阿拉伯数字Convert.chineseToNumberpr#1469@Github
### Bug修复
* 【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 isUseTraditonal 是否使用繁体字金额形式
* @param isUseTraditional 是否使用繁体字金额形式
* @return 中文
* @since 3.2.3
*/
public static String numberToChinese(double number, boolean isUseTraditonal) {
return NumberChineseFormatter.format(number, isUseTraditonal);
public static String numberToChinese(double number, boolean isUseTraditional) {
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;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
/**
@ -37,11 +38,11 @@ public class NumberChineseFormatter {
* 汉字转阿拉伯数字的
*/
private static final ChineseNameValue[] CHINESE_NAME_VALUE = {
new ChineseNameValue("", 10, false),
new ChineseNameValue("", 100, false),
new ChineseNameValue("", 1000, false),
new ChineseNameValue("", 10000, true),
new ChineseNameValue("亿", 100000000, true),
new ChineseNameValue("", 10, false),
new ChineseNameValue("", 100, false),
new ChineseNameValue("", 1000, false),
new ChineseNameValue("", 10000, true),
new ChineseNameValue("亿", 100000000, true),
};
@ -178,10 +179,6 @@ public class NumberChineseFormatter {
* @return 转换后的汉字
*/
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[] units = isUseTraditional ? TRADITIONAL_UNITS : SIMPLE_UNITS;
@ -207,10 +204,16 @@ public class NumberChineseFormatter {
}
/**
* 把中文转换为数字 二百二 220
* @see <url>https://www.d5.nz/read/sfdlq/text-part0000_split_030.html</url>
* 把中文转换为数字 二百二 220<br>
* https://www.d5.nz/read/sfdlq/text-part0000_split_030.html
* <ul>
* <li>一百一十二 - 112</li>
* <li>一千零一十二 - 1012</li>
* </ul>
*
* @param chinese 中文字符
* @return
* @return 数字
* @since 5.6.0
*/
public static int chineseToNumber(String chinese) {
int pos = 0;
@ -218,12 +221,13 @@ public class NumberChineseFormatter {
int section = 0;
int number = 0;
boolean secUnit = false;
while (pos < chinese.length()) {
int num = chineseToValue(chinese.substring(pos, pos + 1));
final int length = chinese.length();
while (pos < length) {
int num = ArrayUtil.indexOf(SIMPLE_DIGITS, chinese.substring(pos, pos + 1));
if (num >= 0) {
number = num;
pos += 1;
if (pos >= chinese.length()) {
if (pos >= length) {
section += number;
rtn += section;
break;
@ -232,8 +236,8 @@ public class NumberChineseFormatter {
int unit = 1;
int tmp = chineseToUnit(chinese.substring(pos, pos + 1));
if (tmp != -1) {
unit = CHINESE_NAME_VALUE[tmp].getValue();
secUnit = CHINESE_NAME_VALUE[tmp].isSecUnit();
unit = CHINESE_NAME_VALUE[tmp].value;
secUnit = CHINESE_NAME_VALUE[tmp].secUnit;
}
if (secUnit) {
section = (section + number) * unit;
@ -254,13 +258,14 @@ public class NumberChineseFormatter {
}
/**
* 中文到数字的转换
* @param chinese
* @return
* 查找对应的权
*
* @param chinese 中文权位名
* @return 位置
*/
private static int chineseToValue(String chinese) {
for (int i = 0; i < SIMPLE_DIGITS.length; i++) {
if (SIMPLE_DIGITS[i].equals(chinese)) {
private static int chineseToUnit(String chinese) {
for (int i = 0; i < CHINESE_NAME_VALUE.length; i++) {
if (CHINESE_NAME_VALUE[i].name.equals(chinese)) {
return i;
}
}
@ -268,16 +273,29 @@ public class NumberChineseFormatter {
}
/**
* 查找对应的权
* @param chinese
* @return
* 权位
*
* @author totalo
* @since 5.6.0
*/
private static int chineseToUnit(String chinese) {
for (int i = 0; i < CHINESE_NAME_VALUE.length; i++) {
if (CHINESE_NAME_VALUE[i].getName().equals(chinese)) {
return i;
}
private static class ChineseNameValue {
/**
* 中文权名称
*/
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
public void chineseToNumberTest(){
Assert.assertEquals(0, NumberChineseFormatter.chineseToNumber(""));
Assert.assertEquals(102, NumberChineseFormatter.chineseToNumber("一百零二"));
Assert.assertEquals(112, NumberChineseFormatter.chineseToNumber("一百一十二"));
Assert.assertEquals(1012, NumberChineseFormatter.chineseToNumber("一千零一十二"));
Assert.assertEquals(1000000, NumberChineseFormatter.chineseToNumber("一百万"));
Assert.assertEquals(2000100112, NumberChineseFormatter.chineseToNumber("二十亿零一十万零一百一十二"));
}
}

View File

@ -15,7 +15,7 @@ import java.util.concurrent.locks.ReentrantLock;
* 定时任务工具类<br>
* 此工具持有一个全局{@link Scheduler}所有定时任务在同一个调度器中执行<br>
* {@link #setMatchSecond(boolean)} 方法用于定义是否使用秒匹配模式如果为true则定时任务表达式中的第一位为秒否则为分默认是分
*
*
* @author xiaoleilu
*
*/
@ -31,7 +31,7 @@ public class CronUtil {
/**
* 自定义定时任务配置文件
*
*
* @param cronSetting 定时任务配置文件
*/
public static void setCronSetting(Setting cronSetting) {
@ -40,7 +40,7 @@ public class CronUtil {
/**
* 自定义定时任务配置文件路径
*
*
* @param cronSettingPath 定时任务配置文件路径相对绝对都可
*/
public static void setCronSetting(String cronSettingPath) {
@ -54,8 +54,8 @@ public class CronUtil {
/**
* 设置是否支持秒匹配<br>
* 此方法用于定义是否使用秒匹配模式如果为true则定时任务表达式中的第一位为秒否则为分默认是分<br>
*
* @param isMatchSecond <code>true</code>支持<code>false</code>不支持
*
* @param isMatchSecond {@code true}支持{@code false}不支持
*/
public static void setMatchSecond(boolean isMatchSecond) {
scheduler.setMatchSecond(isMatchSecond);
@ -63,7 +63,7 @@ public class CronUtil {
/**
* 加入定时任务
*
*
* @param schedulingPattern 定时任务执行时间的crontab表达式
* @param task 任务
* @return 定时任务ID
@ -74,7 +74,7 @@ public class CronUtil {
/**
* 加入定时任务
*
*
* @param id 定时任务ID
* @param schedulingPattern 定时任务执行时间的crontab表达式
* @param task 任务
@ -88,7 +88,7 @@ public class CronUtil {
/**
* 加入定时任务
*
*
* @param schedulingPattern 定时任务执行时间的crontab表达式
* @param task 任务
* @return 定时任务ID
@ -99,7 +99,7 @@ public class CronUtil {
/**
* 批量加入配置文件中的定时任务
*
*
* @param cronSetting 定时任务设置文件
*/
public static void schedule(Setting cronSetting) {
@ -108,7 +108,7 @@ public class CronUtil {
/**
* 移除任务
*
*
* @param schedulerId 任务ID
*/
public static void remove(String schedulerId) {
@ -117,7 +117,7 @@ public class CronUtil {
/**
* 更新Task的执行时间规则
*
*
* @param id Task的ID
* @param pattern {@link CronPattern}
* @since 4.0.10
@ -135,7 +135,7 @@ public class CronUtil {
/**
* 开始非守护线程模式
*
*
* @see #start(boolean)
*/
public static void start() {
@ -144,14 +144,14 @@ public class CronUtil {
/**
* 开始
*
*
* @param isDaemon 是否以守护线程方式启动如果为true则在调用{@link #stop()}方法后执行的定时任务立即结束否则等待执行完毕才结束
*/
synchronized public static void start(boolean isDaemon) {
if (scheduler.isStarted()) {
throw new UtilException("Scheduler has been started, please stop it first!");
}
lock.lock();
try {
if (null == crontabSetting) {
@ -188,7 +188,7 @@ public class CronUtil {
} finally {
lock.unlock();
}
//重新加载任务
schedule(crontabSetting);
//重新启动