mirror of
https://gitee.com/dromara/hutool.git
synced 2025-06-28 13:34:09 +08:00
add chineseToNumber
This commit is contained in:
parent
fc47566ddc
commit
5cdbd16c0b
@ -14,6 +14,7 @@
|
||||
* 【core 】 增加StrMatcher(issue#1379@Github)
|
||||
* 【core 】 NumberUtil增加factorial针对BigInterger方法(issue#1379@Github)
|
||||
* 【core 】 TreeNode增加equals方法(issue#1467@Github)
|
||||
* 【core 】 增加汉字转阿拉伯数字Convert.chineseToNumber(pr#1469@Github)
|
||||
|
||||
### Bug修复
|
||||
* 【socket 】 修复Client创建失败资源未释放问题。
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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{
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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{
|
||||
|
||||
}
|
@ -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("二十亿零一十万零一百一十二"));
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
//重新启动
|
||||
|
Loading…
Reference in New Issue
Block a user