fix chineseFormatter

This commit is contained in:
Looly 2021-07-10 00:36:13 +08:00
parent 9fd7c02c86
commit b8d04654ef
5 changed files with 49 additions and 17 deletions

View File

@ -59,7 +59,7 @@ public class NumberChineseFormatter {
* @return 中文
*/
public static String format(double amount, boolean isUseTraditional, boolean isMoneyMode) {
if (amount > 99999999999999.99 || amount < -99999999999999.99) {
if (amount > 99_9999_9999_9999.99 || amount < -99999999999999.99) {
throw new IllegalArgumentException("Number support only: (-99999999999999.99 99999999999999.99)");
}
@ -77,33 +77,41 @@ public class NumberChineseFormatter {
//将数字以万为单位分为多份
int[] parts = new int[20];
int numParts = 0;
int partsCount = 0;
for (int i = 0; temp != 0; i++) {
int part = (int) (temp % 10000);
parts[i] = part;
numParts++;
partsCount++;
temp = temp / 10000;
}
boolean beforeWanIsZero = true; // 标志下面一级是不是 0
boolean underWanIsZero = true; // 标志下面一级是不是 0
StringBuilder chineseStr = new StringBuilder();
for (int i = 0; i < numParts; i++) {
for (int i = 0; i < partsCount; i++) {
final String partChinese = toChinese(parts[i], isUseTraditional);
if (i % 2 == 0) {
beforeWanIsZero = StrUtil.isEmpty(partChinese);
underWanIsZero = StrUtil.isEmpty(partChinese);
}
// TODO 此处逻辑过于复杂等待整理重构
if (i != 0) {
if (i % 2 == 0) {
if (parts[i - 1] < 1000) {
// 如果"亿"的部分不为 0, "亿"以下的部分小于 1000则亿后面应该跟如一亿零三十五万
chineseStr.insert(0, "");
}
chineseStr.insert(0, "亿");
} else {
if ("".equals(partChinese) && false == beforeWanIsZero) {
if (StrUtil.isEmpty(partChinese) && false == underWanIsZero) {
// 如果对应的 part 0下面一级不为 0则不加而加
chineseStr.insert(0, "");
} else {
if (parts[i - 1] < 1000 && parts[i - 1] > 0) {
// 如果""的部分不为 0, ""前面的部分小于 1000 大于 0 则万后面应该跟
// 如果""的部分不为 0, ""以下的部分小于 1000 大于 0 则万后面应该跟如一万零三百
chineseStr.insert(0, "");
} else if(parts[i] > 0 && parts[i] % 10 == 0){
// 如果万的部分没有个位数需跟如十万零八千
chineseStr.insert(0, "");
}
if (parts[i] > 0) {

View File

@ -23,6 +23,7 @@ import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
/**
* {@link CharSequence} 相关工具类封装
@ -617,6 +618,19 @@ public class CharSequenceUtil {
* @return 除去指定字符后的的字符串如果原字串为{@code null}则返回{@code null}
*/
public static String trim(CharSequence str, int mode) {
return trim(str, mode, CharUtil::isBlankChar);
}
/**
* 按照断言除去字符串头尾部的断言为真的字符如果字符串是{@code null}依然返回{@code null}
*
* @param str 要处理的字符串
* @param mode {@code -1}表示trimStart{@code 0}表示trim全部 {@code 1}表示trimEnd
* @param predicate 断言是否过掉字符返回{@code true}表述过滤掉{@code false}表示不过滤
* @return 除去指定字符后的的字符串如果原字串为{@code null}则返回{@code null}
* @since 5.7.4
*/
public static String trim(CharSequence str, int mode, Predicate<Character> predicate) {
String result;
if (str == null) {
result = null;
@ -625,12 +639,12 @@ public class CharSequenceUtil {
int start = 0;
int end = length;// 扫描字符串头部
if (mode <= 0) {
while ((start < end) && (CharUtil.isBlankChar(str.charAt(start)))) {
while ((start < end) && (predicate.test(str.charAt(start)))) {
start++;
}
}// 扫描字符串尾部
if (mode >= 0) {
while ((start < end) && (CharUtil.isBlankChar(str.charAt(end - 1)))) {
while ((start < end) && (predicate.test(str.charAt(end - 1)))) {
end--;
}
}
@ -3878,7 +3892,7 @@ public class CharSequenceUtil {
* 过滤字符串
*
* @param str 字符串
* @param filter 过滤器
* @param filter 过滤器{@link Filter#accept(Object)}返回为{@code true}的保留字符
* @return 过滤后的字符串
* @since 5.4.0
*/

View File

@ -324,6 +324,10 @@ public final class CsvParser implements Closeable, Serializable {
*/
private void addField(List<String> currentFields, String field) {
final char textDelimiter = this.config.textDelimiter;
// 忽略多余引号后的换行符
field = StrUtil.trim(field, 1, (c-> c == CharUtil.LF || c == CharUtil.CR));
field = StrUtil.unWrap(field, textDelimiter);
field = StrUtil.replace(field, "" + textDelimiter + textDelimiter, textDelimiter + "");
currentFields.add(field);

View File

@ -16,7 +16,7 @@ public class NumberChineseFormatterTest {
f1 = NumberChineseFormatter.format(1024, false);
Assert.assertEquals("一千零二十四", f1);
f1 = NumberChineseFormatter.format(100350089, false);
Assert.assertEquals("一亿三十五万零八十九", f1);
Assert.assertEquals("一亿三十五万零八十九", f1);
f1 = NumberChineseFormatter.format(1200, false);
Assert.assertEquals("一千二百", f1);
f1 = NumberChineseFormatter.format(12, false);
@ -36,11 +36,17 @@ public class NumberChineseFormatterTest {
@Test
public void formatTest3() {
String f1 = NumberChineseFormatter.format(50008000, false, false);
Assert.assertEquals("五千万零八千", f1);
// String f1 = NumberChineseFormatter.format(5000_8000, false, false);
// Assert.assertEquals("五千万零八千", f1);
f1 = NumberChineseFormatter.format(100350089, false, false);
Assert.assertEquals("一亿零三十五万零八十九\"", f1);
String f2 = NumberChineseFormatter.format(1_0035_0089, false, false);
Assert.assertEquals("一亿零三十五万零八十九", f2);
}
@Test
public void formatMaxTest() {
String f3 = NumberChineseFormatter.format(99_9999_9999_9999L, false, false);
Assert.assertEquals("九十九万九千九百九十九亿九千九百九十九万九千九百九十九", f3);
}
@Test
@ -54,7 +60,7 @@ public class NumberChineseFormatterTest {
f1 = NumberChineseFormatter.format(1024, true);
Assert.assertEquals("壹仟零贰拾肆", f1);
f1 = NumberChineseFormatter.format(100350089, true);
Assert.assertEquals("壹亿叁拾伍万零捌拾玖", f1);
Assert.assertEquals("壹亿叁拾伍万零捌拾玖", f1);
f1 = NumberChineseFormatter.format(1200, true);
Assert.assertEquals("壹仟贰佰", f1);
f1 = NumberChineseFormatter.format(12, true);

0
hutool-core/src/test/resources/test.csv Normal file → Executable file
View File

Can't render this file because it contains an unexpected character in line 2 and column 33.