diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8d597b6df..6decf0615 100755
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@
* 【core 】 修复注解工具类getAnnotations的NPE问题,注解扫描器添新功能(pr#671@Gitee)
* 【core 】 合成注解SyntheticAnnotation提取为接口,并为实现类添加注解选择器和属性处理器(pr#678@Gitee)
* 【core 】 增加BeanValueProvider(issue#I5FBHV@Gitee)
+* 【core 】 Convert工具类中,新增中文大写数字金额转换为数字工具方法(pr#674@Gitee)
*
### 🐞Bug修复
diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/Convert.java b/hutool-core/src/main/java/cn/hutool/core/convert/Convert.java
index 869104f97..a67682904 100755
--- a/hutool-core/src/main/java/cn/hutool/core/convert/Convert.java
+++ b/hutool-core/src/main/java/cn/hutool/core/convert/Convert.java
@@ -1033,80 +1033,10 @@ public class Convert {
*
* @param chineseMoneyAmount 中文大写数字金额
* @return 返回结果以元为单位的BigDecimal类型数字
+ * @since 5.8.5
*/
- public static BigDecimal chineseMoneyAmount2Number(String chineseMoneyAmount){
- if(StrUtil.isBlank(chineseMoneyAmount)){
- return null;
- }
-
- int yi = chineseMoneyAmount.indexOf("元");
- if(yi == -1){
- yi = chineseMoneyAmount.indexOf("圆");
- }
- int ji = chineseMoneyAmount.indexOf("角");
- 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 = NumberChineseFormatter.chineseToNumber(yStr);
- }
- if(StrUtil.isNotBlank(jStr)){
- j = NumberChineseFormatter.chineseToNumber(jStr);
- }
- if(StrUtil.isNotBlank(fStr)){
- f = NumberChineseFormatter.chineseToNumber(fStr);
- }
-
- BigDecimal amount = new BigDecimal(y);
- amount = amount.add(BigDecimal.valueOf(j).divide(BigDecimal.TEN));
- amount = amount.add(BigDecimal.valueOf(f).divide(BigDecimal.valueOf(100)));
- return amount;
+ public static BigDecimal chineseMoneyToNumber(String chineseMoneyAmount){
+ return NumberChineseFormatter.chineseMoneyToNumber(chineseMoneyAmount);
}
// -------------------------------------------------------------------------- 数字转换
diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/NumberChineseFormatter.java b/hutool-core/src/main/java/cn/hutool/core/convert/NumberChineseFormatter.java
index 6ec3f0e16..ebf0be822 100644
--- a/hutool-core/src/main/java/cn/hutool/core/convert/NumberChineseFormatter.java
+++ b/hutool-core/src/main/java/cn/hutool/core/convert/NumberChineseFormatter.java
@@ -5,6 +5,9 @@ import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
/**
* 数字转中文类
* 包括:
@@ -232,6 +235,86 @@ public class NumberChineseFormatter {
return String.valueOf(numberToChinese(c - '0', isUseTraditional));
}
+ /**
+ * 中文大写数字金额转换为数字,返回结果以元为单位的BigDecimal类型数字
+ *
+ * 如:
+ * “陆万柒仟伍佰伍拾陆元叁角贰分”返回“67556.32”
+ * “叁角贰分”返回“0.32”
+ *
+ * @param chineseMoneyAmount 中文大写数字金额
+ * @return 返回结果以元为单位的BigDecimal类型数字
+ */
+ @SuppressWarnings("ConstantConditions")
+ public static BigDecimal chineseMoneyToNumber(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 = NumberChineseFormatter.chineseToNumber(yStr);
+ }
+ if(StrUtil.isNotBlank(jStr)){
+ j = NumberChineseFormatter.chineseToNumber(jStr);
+ }
+ if(StrUtil.isNotBlank(fStr)){
+ f = NumberChineseFormatter.chineseToNumber(fStr);
+ }
+
+ BigDecimal amount = new BigDecimal(y);
+ amount = amount.add(BigDecimal.valueOf(j).divide(BigDecimal.TEN, RoundingMode.HALF_UP));
+ amount = amount.add(BigDecimal.valueOf(f).divide(BigDecimal.valueOf(100), RoundingMode.HALF_UP));
+ return amount;
+ }
+
/**
* 阿拉伯数字整数部分转换成中文,只支持正数
*
diff --git a/hutool-core/src/main/java/cn/hutool/core/text/CharSequenceUtil.java b/hutool-core/src/main/java/cn/hutool/core/text/CharSequenceUtil.java
index d38e31ee0..50c6b59c4 100755
--- a/hutool-core/src/main/java/cn/hutool/core/text/CharSequenceUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/text/CharSequenceUtil.java
@@ -86,8 +86,7 @@ public class CharSequenceUtil {
* @see #isEmpty(CharSequence)
*/
public static boolean isBlank(CharSequence str) {
- int length;
-
+ final int length;
if ((str == null) || ((length = str.length()) == 0)) {
return true;
}
diff --git a/hutool-core/src/test/java/cn/hutool/core/convert/ConvertTest.java b/hutool-core/src/test/java/cn/hutool/core/convert/ConvertTest.java
index ce245edb7..43c7ea09b 100755
--- a/hutool-core/src/test/java/cn/hutool/core/convert/ConvertTest.java
+++ b/hutool-core/src/test/java/cn/hutool/core/convert/ConvertTest.java
@@ -5,10 +5,8 @@ import cn.hutool.core.date.DateException;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.map.MapUtil;
-import cn.hutool.core.math.Money;
import cn.hutool.core.util.ByteUtil;
import cn.hutool.core.util.HexUtil;
-import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
@@ -40,33 +38,33 @@ public class ConvertTest {
@Test
public void toObjectTest() {
- Object result = Convert.convert(Object.class, "aaaa");
+ final Object result = Convert.convert(Object.class, "aaaa");
Assert.assertEquals("aaaa", result);
}
@Test
public void toStrTest() {
- int a = 1;
- long[] b = { 1, 2, 3, 4, 5 };
+ final int a = 1;
+ final long[] b = { 1, 2, 3, 4, 5 };
Assert.assertEquals("[1, 2, 3, 4, 5]", Convert.convert(String.class, b));
- String aStr = Convert.toStr(a);
+ final String aStr = Convert.toStr(a);
Assert.assertEquals("1", aStr);
- String bStr = Convert.toStr(b);
+ final String bStr = Convert.toStr(b);
Assert.assertEquals("[1, 2, 3, 4, 5]", Convert.toStr(bStr));
}
@Test
public void toStrTest2() {
- String result = Convert.convert(String.class, "aaaa");
+ final String result = Convert.convert(String.class, "aaaa");
Assert.assertEquals("aaaa", result);
}
@Test
public void toStrTest3() {
- char a = 'a';
- String result = Convert.convert(String.class, a);
+ final char a = 'a';
+ final String result = Convert.convert(String.class, a);
Assert.assertEquals("a", result);
}
@@ -80,160 +78,160 @@ public class ConvertTest {
@Test
public void toIntTest() {
- String a = " 34232";
- Integer aInteger = Convert.toInt(a);
+ final String a = " 34232";
+ final Integer aInteger = Convert.toInt(a);
Assert.assertEquals(Integer.valueOf(34232), aInteger);
- int aInt = ConverterRegistry.getInstance().convert(int.class, a);
+ final int aInt = ConverterRegistry.getInstance().convert(int.class, a);
Assert.assertEquals(34232, aInt);
// 带小数测试
- String b = " 34232.00";
- Integer bInteger = Convert.toInt(b);
+ final String b = " 34232.00";
+ final Integer bInteger = Convert.toInt(b);
Assert.assertEquals(Integer.valueOf(34232), bInteger);
- int bInt = ConverterRegistry.getInstance().convert(int.class, b);
+ final int bInt = ConverterRegistry.getInstance().convert(int.class, b);
Assert.assertEquals(34232, bInt);
// boolean测试
- boolean c = true;
- Integer cInteger = Convert.toInt(c);
+ final boolean c = true;
+ final Integer cInteger = Convert.toInt(c);
Assert.assertEquals(Integer.valueOf(1), cInteger);
- int cInt = ConverterRegistry.getInstance().convert(int.class, c);
+ final int cInt = ConverterRegistry.getInstance().convert(int.class, c);
Assert.assertEquals(1, cInt);
// boolean测试
- String d = "08";
- Integer dInteger = Convert.toInt(d);
+ final String d = "08";
+ final Integer dInteger = Convert.toInt(d);
Assert.assertEquals(Integer.valueOf(8), dInteger);
- int dInt = ConverterRegistry.getInstance().convert(int.class, d);
+ final int dInt = ConverterRegistry.getInstance().convert(int.class, d);
Assert.assertEquals(8, dInt);
}
@Test
public void toIntTest2() {
- ArrayList array = new ArrayList<>();
- Integer aInt = Convert.convertQuietly(Integer.class, array, -1);
+ final ArrayList array = new ArrayList<>();
+ final Integer aInt = Convert.convertQuietly(Integer.class, array, -1);
Assert.assertEquals(Integer.valueOf(-1), aInt);
}
@Test
public void toLongTest() {
- String a = " 342324545435435";
- Long aLong = Convert.toLong(a);
+ final String a = " 342324545435435";
+ final Long aLong = Convert.toLong(a);
Assert.assertEquals(Long.valueOf(342324545435435L), aLong);
- long aLong2 = ConverterRegistry.getInstance().convert(long.class, a);
+ final long aLong2 = ConverterRegistry.getInstance().convert(long.class, a);
Assert.assertEquals(342324545435435L, aLong2);
// 带小数测试
- String b = " 342324545435435.245435435";
- Long bLong = Convert.toLong(b);
+ final String b = " 342324545435435.245435435";
+ final Long bLong = Convert.toLong(b);
Assert.assertEquals(Long.valueOf(342324545435435L), bLong);
- long bLong2 = ConverterRegistry.getInstance().convert(long.class, b);
+ final long bLong2 = ConverterRegistry.getInstance().convert(long.class, b);
Assert.assertEquals(342324545435435L, bLong2);
// boolean测试
- boolean c = true;
- Long cLong = Convert.toLong(c);
+ final boolean c = true;
+ final Long cLong = Convert.toLong(c);
Assert.assertEquals(Long.valueOf(1), cLong);
- long cLong2 = ConverterRegistry.getInstance().convert(long.class, c);
+ final long cLong2 = ConverterRegistry.getInstance().convert(long.class, c);
Assert.assertEquals(1, cLong2);
// boolean测试
- String d = "08";
- Long dLong = Convert.toLong(d);
+ final String d = "08";
+ final Long dLong = Convert.toLong(d);
Assert.assertEquals(Long.valueOf(8), dLong);
- long dLong2 = ConverterRegistry.getInstance().convert(long.class, d);
+ final long dLong2 = ConverterRegistry.getInstance().convert(long.class, d);
Assert.assertEquals(8, dLong2);
}
@Test
public void toCharTest() {
- String str = "aadfdsfs";
- Character c = Convert.toChar(str);
+ final String str = "aadfdsfs";
+ final Character c = Convert.toChar(str);
Assert.assertEquals(Character.valueOf('a'), c);
// 转换失败
- Object str2 = "";
- Character c2 = Convert.toChar(str2);
+ final Object str2 = "";
+ final Character c2 = Convert.toChar(str2);
Assert.assertNull(c2);
}
@Test
public void toNumberTest() {
- Object a = "12.45";
- Number number = Convert.toNumber(a);
+ final Object a = "12.45";
+ final Number number = Convert.toNumber(a);
Assert.assertEquals(12.45D, number.doubleValue(), 2);
}
@Test
public void emptyToNumberTest() {
- Object a = "";
- Number number = Convert.toNumber(a);
+ final Object a = "";
+ final Number number = Convert.toNumber(a);
Assert.assertNull(number);
}
@Test
public void intAndByteConvertTest() {
// 测试 int 转 byte
- int int0 = 234;
- byte byte0 = Convert.intToByte(int0);
+ final int int0 = 234;
+ final byte byte0 = Convert.intToByte(int0);
Assert.assertEquals(-22, byte0);
- int int1 = Convert.byteToUnsignedInt(byte0);
+ final int int1 = Convert.byteToUnsignedInt(byte0);
Assert.assertEquals(int0, int1);
}
@Test
public void intAndBytesTest() {
// 测试 int 转 byte 数组
- int int2 = 1417;
- byte[] bytesInt = Convert.intToBytes(int2);
+ final int int2 = 1417;
+ final byte[] bytesInt = Convert.intToBytes(int2);
// 测试 byte 数组转 int
- int int3 = Convert.bytesToInt(bytesInt);
+ final int int3 = Convert.bytesToInt(bytesInt);
Assert.assertEquals(int2, int3);
}
@Test
public void longAndBytesTest() {
// 测试 long 转 byte 数组
- long long1 = 2223;
+ final long long1 = 2223;
- byte[] bytesLong = Convert.longToBytes(long1);
- long long2 = Convert.bytesToLong(bytesLong);
+ final byte[] bytesLong = Convert.longToBytes(long1);
+ final long long2 = Convert.bytesToLong(bytesLong);
Assert.assertEquals(long1, long2);
}
@Test
public void shortAndBytesTest() {
- short short1 = 122;
- byte[] bytes = Convert.shortToBytes(short1);
- short short2 = Convert.bytesToShort(bytes);
+ final short short1 = 122;
+ final byte[] bytes = Convert.shortToBytes(short1);
+ final short short2 = Convert.bytesToShort(bytes);
Assert.assertEquals(short2, short1);
}
@Test
public void toListTest() {
- List list = Arrays.asList("1", "2");
- String str = Convert.toStr(list);
- List list2 = Convert.toList(String.class, str);
+ final List list = Arrays.asList("1", "2");
+ final String str = Convert.toStr(list);
+ final List list2 = Convert.toList(String.class, str);
Assert.assertEquals("1", list2.get(0));
Assert.assertEquals("2", list2.get(1));
- List list3 = Convert.toList(Integer.class, str);
+ final List list3 = Convert.toList(Integer.class, str);
Assert.assertEquals(1, list3.get(0).intValue());
Assert.assertEquals(2, list3.get(1).intValue());
}
@Test
public void toListTest2(){
- String str = "1,2";
- List list2 = Convert.toList(String.class, str);
+ final String str = "1,2";
+ final List list2 = Convert.toList(String.class, str);
Assert.assertEquals("1", list2.get(0));
Assert.assertEquals("2", list2.get(1));
- List list3 = Convert.toList(Integer.class, str);
+ final List list3 = Convert.toList(Integer.class, str);
Assert.assertEquals(1, list3.get(0).intValue());
Assert.assertEquals(2, list3.get(1).intValue());
}
@@ -259,14 +257,14 @@ public class ConvertTest {
@Test
public void toAtomicIntegerArrayTest(){
- String str = "1,2";
+ final String str = "1,2";
final AtomicIntegerArray atomicIntegerArray = Convert.convert(AtomicIntegerArray.class, str);
Assert.assertEquals("[1, 2]", atomicIntegerArray.toString());
}
@Test
public void toAtomicLongArrayTest(){
- String str = "1,2";
+ final String str = "1,2";
final AtomicLongArray atomicLongArray = Convert.convert(AtomicLongArray.class, str);
Assert.assertEquals("[1, 2]", atomicLongArray.toString());
}
@@ -312,7 +310,7 @@ public class ConvertTest {
private final int id;
private final String name;
- BuildingType(int id, String name){
+ BuildingType(final int id, final String name){
this.id = id;
this.name = name;
}
@@ -338,7 +336,7 @@ public class ConvertTest {
@Test
public void toHashtableTest(){
- Map map = MapUtil.newHashMap();
+ final Map map = MapUtil.newHashMap();
map.put("a1", "v1");
map.put("a2", "v2");
map.put("a3", "v3");
@@ -353,7 +351,7 @@ public class ConvertTest {
@Test
public void toBigDecimalTest(){
// https://github.com/dromara/hutool/issues/1818
- String str = "33020000210909112800000124";
+ final String str = "33020000210909112800000124";
final BigDecimal bigDecimal = Convert.toBigDecimal(str);
Assert.assertEquals(str, bigDecimal.toPlainString());
}
@@ -361,7 +359,7 @@ public class ConvertTest {
@Test
public void toFloatTest(){
// https://gitee.com/dromara/hutool/issues/I4M0E4
- String hex2 = "CD0CCB43";
+ final String hex2 = "CD0CCB43";
final byte[] value = HexUtil.decodeHex(hex2);
final float f = Convert.toFloat(value);
Assert.assertEquals(406.1F, f, 2);
@@ -369,22 +367,22 @@ public class ConvertTest {
@Test
public void floatToDoubleTest(){
- float a = 0.45f;
- double b = Convert.toDouble(a);
+ final float a = 0.45f;
+ final double b = Convert.toDouble(a);
Assert.assertEquals(a, b, 5);
}
@Test
public void floatToDoubleAddrTest(){
- float a = 0.45f;
+ final float a = 0.45f;
final DoubleAdder adder = Convert.convert(DoubleAdder.class, a);
Assert.assertEquals(a, adder.doubleValue(), 5);
}
@Test
public void doubleToFloatTest(){
- double a = 0.45f;
- float b = Convert.toFloat(a);
+ final double a = 0.45f;
+ final float b = Convert.toFloat(a);
Assert.assertEquals(a, b, 5);
}
@@ -408,22 +406,7 @@ public class ConvertTest {
}
@Test
- public void testChineseMoneyAmount2Number(){
- String[] strs = new String[]{
- "陆万柒仟伍佰伍拾陆圆",
- "陆万柒仟伍佰伍拾陆元",
- "叁角",
- "贰分",
- "陆万柒仟伍佰伍拾陆元叁角",
- "陆万柒仟伍佰伍拾陆元贰分",
- "叁角贰分",
- "陆万柒仟伍佰伍拾陆元叁角贰分",
- };
-
- for(String s: strs) {
- System.out.println("s="+s+", n="+Convert.chineseMoneyAmount2Number(s));
- }
-
+ public void testChineseMoneyToNumber(){
/*
* s=陆万柒仟伍佰伍拾陆圆, n=67556
* s=陆万柒仟伍佰伍拾陆元, n=67556
@@ -434,6 +417,14 @@ public class ConvertTest {
* s=叁角贰分, n=0.32
* s=陆万柒仟伍佰伍拾陆元叁角贰分, n=67556.32
*/
+ Assert.assertEquals(67556, Convert.chineseMoneyToNumber("陆万柒仟伍佰伍拾陆圆").longValue());
+ Assert.assertEquals(67556, Convert.chineseMoneyToNumber("陆万柒仟伍佰伍拾陆元").longValue());
+ Assert.assertEquals(0.3D, Convert.chineseMoneyToNumber("叁角").doubleValue(), 2);
+ Assert.assertEquals(0.02, Convert.chineseMoneyToNumber("贰分").doubleValue(), 2);
+ Assert.assertEquals(67556.3, Convert.chineseMoneyToNumber("陆万柒仟伍佰伍拾陆元叁角").doubleValue(), 2);
+ Assert.assertEquals(67556.02, Convert.chineseMoneyToNumber("陆万柒仟伍佰伍拾陆元贰分").doubleValue(), 2);
+ Assert.assertEquals(0.32, Convert.chineseMoneyToNumber("叁角贰分").doubleValue(), 2);
+ Assert.assertEquals(67556.32, Convert.chineseMoneyToNumber("陆万柒仟伍佰伍拾陆元叁角贰分").doubleValue(), 2);
}