From a7fde0338b57c2f4e798dd45d78945758d7bbe37 Mon Sep 17 00:00:00 2001 From: looly Date: Wed, 1 Dec 2021 16:44:05 +0800 Subject: [PATCH] fix date chinese bug --- CHANGELOG.md | 1 + .../core/convert/NumberChineseFormatter.java | 48 +++++++++++++- .../cn/hutool/core/date/CalendarUtil.java | 16 ++--- .../cn/hutool/core/date/DateUtilTest.java | 63 ++++++++++--------- 4 files changed, 89 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3932213bd..35a8e7bf0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ * 【poi 】 修复读取日期类型的自定义样式单元格时间结果为1899年问题(pr#1977@Github) * 【poi 】 修复SoapClient参数未使用问题 * 【core 】 修复HashUtil.cityHash128参数未使用问题 +* 【core 】 修复DateUtil.formatChineseDate显示问题(issue#I4KK5F@Gitee) ------------------------------------------------------------------------------------------------------------- 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 b794d9104..afbb9d472 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 @@ -64,7 +64,7 @@ public class NumberChineseFormatter { return "零"; } Assert.checkBetween(amount, -99_9999_9999_9999.99, 99_9999_9999_9999.99, - "Number support only: (-99999999999999.99 ~ 99999999999999.99)!"); + "Number support only: (-99999999999999.99 ~ 99999999999999.99)!"); final StringBuilder chineseStr = new StringBuilder(); @@ -126,6 +126,52 @@ public class NumberChineseFormatter { return chineseStr.toString(); } + /** + * 阿拉伯数字(支持正负整数)转换成中文 + * + * @param amount 数字 + * @param isUseTraditional 是否使用繁体 + * @return 中文 + * @since 5.7.17 + */ + public static String format(long amount, boolean isUseTraditional){ + if(0 == amount){ + return "零"; + } + Assert.checkBetween(amount, -99_9999_9999_9999.99, 99_9999_9999_9999.99, + "Number support only: (-99999999999999.99 ~ 99999999999999.99)!"); + + final StringBuilder chineseStr = new StringBuilder(); + + // 负数 + if (amount < 0) { + chineseStr.append("负"); + amount = -amount; + } + + chineseStr.append(longToChinese(amount, isUseTraditional)); + return chineseStr.toString(); + } + + /** + * 格式化-999~999之间的数字
+ * 这个方法显示10~19以下的数字时使用"十一"而非"一十一"。 + * + * @param amount 数字 + * @param isUseTraditional 是否使用繁体 + * @return 中文 + * @since 5.7.17 + */ + public static String formatThousand(int amount, boolean isUseTraditional){ + Assert.checkBetween(amount, -999, 999, "Number support only: (-999 ~ 999)!"); + final String chinese = thousandToChinese(amount, isUseTraditional); + if(amount < 20 && amount > 10){ + // "十一"而非"一十一" + return chinese.substring(1); + } + return chinese; + } + /** * 数字字符转中文,非数字字符原样返回 * diff --git a/hutool-core/src/main/java/cn/hutool/core/date/CalendarUtil.java b/hutool-core/src/main/java/cn/hutool/core/date/CalendarUtil.java index cb9aa732f..752a052c8 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/CalendarUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/CalendarUtil.java @@ -525,8 +525,8 @@ public class CalendarUtil { * 将指定Calendar时间格式化为纯中文形式,比如: * *
-	 *     2018-02-24 12:13:14转换为 二〇一八年二月二十四日(withTime为false)
-	 *     2018-02-24 12:13:14 转换为 二〇一八年二月二十四日一十二时一十三分一十四秒(withTime为true)
+	 *     2018-02-24 12:13:14 转换为 二〇一八年二月二十四日(withTime为false)
+	 *     2018-02-24 12:13:14 转换为 二〇一八年二月二十四日十二时十三分十四秒(withTime为true)
 	 * 
* * @param calendar {@link Calendar} @@ -538,7 +538,7 @@ public class CalendarUtil { final StringBuilder result = StrUtil.builder(); // 年 - String year = String.valueOf(calendar.get(Calendar.YEAR)); + final String year = String.valueOf(calendar.get(Calendar.YEAR)); final int length = year.length(); for (int i = 0; i < length; i++) { result.append(NumberChineseFormatter.numberCharToChinese(year.charAt(i), false)); @@ -547,26 +547,26 @@ public class CalendarUtil { // 月 int month = calendar.get(Calendar.MONTH) + 1; - result.append(NumberChineseFormatter.format(month, false)); + result.append(NumberChineseFormatter.formatThousand(month, false)); result.append('月'); // 日 int day = calendar.get(Calendar.DAY_OF_MONTH); - result.append(NumberChineseFormatter.format(day, false)); + result.append(NumberChineseFormatter.formatThousand(day, false)); result.append('日'); if (withTime) { // 时 int hour = calendar.get(Calendar.HOUR_OF_DAY); - result.append(NumberChineseFormatter.format(hour, false)); + result.append(NumberChineseFormatter.formatThousand(hour, false)); result.append('时'); // 分 int minute = calendar.get(Calendar.MINUTE); - result.append(NumberChineseFormatter.format(minute, false)); + result.append(NumberChineseFormatter.formatThousand(minute, false)); result.append('分'); // 秒 int second = calendar.get(Calendar.SECOND); - result.append(NumberChineseFormatter.format(second, false)); + result.append(NumberChineseFormatter.formatThousand(second, false)); result.append('秒'); } diff --git a/hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java index 738995533..8495eccd5 100644 --- a/hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java @@ -116,7 +116,7 @@ public class DateUtilTest { } @Test - public void truncateTest(){ + public void truncateTest() { String dateStr2 = "2020-02-29 12:59:34"; Date date2 = DateUtil.parse(dateStr2); final DateTime dateTime = DateUtil.truncate(date2, DateField.MINUTE); @@ -124,7 +124,7 @@ public class DateUtilTest { } @Test - public void ceilingMinuteTest(){ + public void ceilingMinuteTest() { String dateStr2 = "2020-02-29 12:59:34"; Date date2 = DateUtil.parse(dateStr2); @@ -137,7 +137,7 @@ public class DateUtilTest { } @Test - public void ceilingDayTest(){ + public void ceilingDayTest() { String dateStr2 = "2020-02-29 12:59:34"; Date date2 = DateUtil.parse(dateStr2); @@ -279,13 +279,16 @@ public class DateUtilTest { public void formatChineseDateTest() { String formatChineseDate = DateUtil.formatChineseDate(DateUtil.parse("2018-02-24"), true, false); Assert.assertEquals("二〇一八年二月二十四日", formatChineseDate); + + formatChineseDate = DateUtil.formatChineseDate(DateUtil.parse("2018-02-14"), true, false); + Assert.assertEquals("二〇一八年二月十四日", formatChineseDate); } - @Test - public void formatChineseDateTimeTest() { - String formatChineseDateTime = DateUtil.formatChineseDate(DateUtil.parse("2018-02-24 12:13:14"), true, true); - Assert.assertEquals("二〇一八年二月二十四日一十二时一十三分一十四秒", formatChineseDateTime); - } + @Test + public void formatChineseDateTimeTest() { + String formatChineseDateTime = DateUtil.formatChineseDate(DateUtil.parse("2018-02-24 12:13:14"), true, true); + Assert.assertEquals("二〇一八年二月二十四日十二时十三分十四秒", formatChineseDateTime); + } @Test public void formatBetweenTest() { @@ -666,24 +669,24 @@ public class DateUtilTest { } @Test - public void parseUTCTest2(){ + public void parseUTCTest2() { // issue1503@Github // 检查不同毫秒长度都可以正常匹配 - String utcTime="2021-03-30T12:56:51.3Z"; + String utcTime = "2021-03-30T12:56:51.3Z"; DateTime parse = DateUtil.parseUTC(utcTime); Assert.assertEquals("2021-03-30 12:56:51", parse.toString()); - utcTime="2021-03-30T12:56:51.34Z"; + utcTime = "2021-03-30T12:56:51.34Z"; parse = DateUtil.parseUTC(utcTime); Assert.assertEquals("2021-03-30 12:56:51", parse.toString()); - utcTime="2021-03-30T12:56:51.345Z"; + utcTime = "2021-03-30T12:56:51.345Z"; parse = DateUtil.parseUTC(utcTime); Assert.assertEquals("2021-03-30 12:56:51", parse.toString()); } @Test - public void parseCSTTest(){ + public void parseCSTTest() { String dateStr = "Wed Sep 16 11:26:23 CST 2009"; SimpleDateFormat sdf = new SimpleDateFormat(DatePattern.JDK_DATETIME_PATTERN, Locale.US); @@ -697,7 +700,7 @@ public class DateUtilTest { } @Test - public void parseCSTTest2(){ + public void parseCSTTest2() { String dateStr = "Wed Sep 16 11:26:23 CST 2009"; SimpleDateFormat sdf = new SimpleDateFormat(DatePattern.JDK_DATETIME_PATTERN, Locale.US); @@ -737,7 +740,7 @@ public class DateUtilTest { Date date = DateUtil.endOfQuarter( DateUtil.parse("2020-05-31 00:00:00")); - Assert.assertEquals("2020-06-30 23:59:59", DateUtil.format(date,"yyyy-MM-dd HH:mm:ss")); + Assert.assertEquals("2020-06-30 23:59:59", DateUtil.format(date, "yyyy-MM-dd HH:mm:ss")); } @Test @@ -803,7 +806,7 @@ public class DateUtilTest { } @Test - public void toInstantTest(){ + public void toInstantTest() { LocalDateTime localDateTime = LocalDateTime.parse("2017-05-06T08:30:00", DateTimeFormatter.ISO_DATE_TIME); Instant instant = DateUtil.toInstant(localDateTime); Assert.assertEquals("2017-05-06T00:30:00Z", instant.toString()); @@ -818,7 +821,7 @@ public class DateUtilTest { } @Test - public void dateTest(){ + public void dateTest() { //LocalDateTime ==> date LocalDateTime localDateTime = LocalDateTime.parse("2017-05-06T08:30:00", DateTimeFormatter.ISO_DATE_TIME); DateTime date = DateUtil.date(localDateTime); @@ -828,11 +831,11 @@ public class DateUtilTest { LocalDate localDate = localDateTime.toLocalDate(); DateTime date2 = DateUtil.date(localDate); Assert.assertEquals("2017-05-06", - DateUtil.format(date2, DatePattern.NORM_DATE_PATTERN)); + DateUtil.format(date2, DatePattern.NORM_DATE_PATTERN)); } @Test - public void dateTest2(){ + public void dateTest2() { // 测试负数日期 long dateLong = -1497600000; final DateTime date = DateUtil.date(dateLong); @@ -840,7 +843,7 @@ public class DateUtilTest { } @Test - public void ageTest(){ + public void ageTest() { String d1 = "2000-02-29"; String d2 = "2018-02-28"; final int age = DateUtil.age(DateUtil.parseDate(d1), DateUtil.parseDate(d2)); @@ -848,14 +851,14 @@ public class DateUtilTest { } @Test(expected = IllegalArgumentException.class) - public void ageTest2(){ + public void ageTest2() { String d1 = "2019-02-29"; String d2 = "2018-02-28"; DateUtil.age(DateUtil.parseDate(d1), DateUtil.parseDate(d2)); } @Test - public void isExpiredTest(){ + public void isExpiredTest() { DateTime startDate = DateUtil.parse("2019-12-01 17:02:30"); DateTime endDate = DateUtil.parse("2019-12-02 17:02:30"); int length = 3; @@ -916,7 +919,7 @@ public class DateUtilTest { @SuppressWarnings("ConstantConditions") @Test - public void parseSingleNumberTest(){ + public void parseSingleNumberTest() { DateTime dateTime = DateUtil.parse("2020-5-08"); Assert.assertEquals("2020-05-08 00:00:00", dateTime.toString()); dateTime = DateUtil.parse("2020-5-8"); @@ -938,21 +941,21 @@ public class DateUtilTest { @SuppressWarnings("ConstantConditions") @Test - public void parseISO8601Test(){ + public void parseISO8601Test() { String dt = "2020-06-03 12:32:12,333"; final DateTime parse = DateUtil.parse(dt); Assert.assertEquals("2020-06-03 12:32:12", parse.toString()); } @Test(expected = DateException.class) - public void parseNotFitTest(){ + public void parseNotFitTest() { //https://github.com/looly/hutool/issues/1332 // 在日期格式不匹配的时候,测试是否正常报错 DateUtil.parse("2020-12-23", DatePattern.PURE_DATE_PATTERN); } @Test - public void formatTest(){ + public void formatTest() { Calendar calendar = new GregorianCalendar(); calendar.set(2021, Calendar.JULY, 14, 23, 59, 59); Date date = new DateTime(calendar); @@ -963,7 +966,7 @@ public class DateUtilTest { } @Test - public void formatNormDateTimeFormatterTest(){ + public void formatNormDateTimeFormatterTest() { String format = DateUtil.format(DateUtil.parse("2021-07-14 10:05:38"), DatePattern.NORM_DATETIME_FORMATTER); Assert.assertEquals("2021-07-14 10:05:38", format); @@ -973,7 +976,7 @@ public class DateUtilTest { } @Test - public void isWeekendTest(){ + public void isWeekendTest() { DateTime parse = DateUtil.parse("2021-07-28"); Assert.assertFalse(DateUtil.isWeekend(parse)); @@ -984,14 +987,14 @@ public class DateUtilTest { } @Test - public void parseSingleMonthAndDayTest(){ + public void parseSingleMonthAndDayTest() { final DateTime parse = DateUtil.parse("2021-1-1"); Assert.assertNotNull(parse); Assert.assertEquals("2021-01-01 00:00:00", parse.toString()); } @Test - public void parseByDateTimeFormatterTest(){ + public void parseByDateTimeFormatterTest() { final DateTime parse = DateUtil.parse("2021-12-01", DatePattern.NORM_DATE_FORMATTER); Assert.assertEquals("2021-12-01 00:00:00", parse.toString()); }