From 175881681c406fb2aa2dc1cf1f6a24be26562b6b Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 14 Dec 2023 23:28:10 +0800 Subject: [PATCH] fix code --- .../dromara/hutool/core/date/DateUtil.java | 21 +----- .../core/date/format/FastDateFormat.java | 5 +- .../core/date/format/GlobalCustomFormat.java | 4 +- .../core/date/format/parser/DateParser.java | 17 +---- .../date/format/parser/FastDateParser.java | 39 ++--------- .../date/format/parser/ISO8601DateParser.java | 2 +- .../date/format/parser/NormalDateParser.java | 2 +- .../format/parser/PositionDateParser.java | 12 ---- .../format/parser/PredicateDateParser.java | 3 +- .../format/parser/RegisterDateParser.java | 68 +++++++++++++++++++ .../core/date/format/parser/package-info.java | 9 ++- 11 files changed, 96 insertions(+), 86 deletions(-) create mode 100644 hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/RegisterDateParser.java diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/DateUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/DateUtil.java index 6c9998fed..a2bff803b 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/DateUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/DateUtil.java @@ -19,9 +19,6 @@ import org.dromara.hutool.core.date.format.FastDateFormat; import org.dromara.hutool.core.date.format.GlobalCustomFormat; import org.dromara.hutool.core.date.format.parser.*; import org.dromara.hutool.core.lang.Assert; -import org.dromara.hutool.core.math.NumberUtil; -import org.dromara.hutool.core.regex.PatternPool; -import org.dromara.hutool.core.regex.ReUtil; import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.text.split.SplitUtil; @@ -807,21 +804,9 @@ public class DateUtil extends CalendarUtil { // 去掉两边空格并去掉中文日期中的“日”和“秒”,以规范长度 dateStr = StrUtil.removeAll(dateStr.trim(), '日', '秒'); - if (PureDateParser.INSTANCE.test(dateStr)) { - // 纯数字形式 - return PureDateParser.INSTANCE.parse(dateStr); - } else if (TimeParser.INSTANCE.test(dateStr)) { - // HH:mm:ss 或者 HH:mm 时间格式匹配单独解析 - return TimeParser.INSTANCE.parse(dateStr); - } else if (CSTDateParser.INSTANCE.test(dateStr)) { - // JDK的Date对象toString默认格式,类似于: - // Tue Jun 4 16:25:15 +0800 2019 - // Thu May 16 17:57:18 GMT+08:00 2019 - // Wed Aug 01 00:00:00 CST 2012 - return CSTDateParser.INSTANCE.parse(dateStr); - } else if (ISO8601DateParser.INSTANCE.test(dateStr)) { - // ISO8601标准时间 - return ISO8601DateParser.INSTANCE.parse(dateStr); + final Date result = RegisterDateParser.INSTANCE.parse(dateStr); + if(null != result){ + return date(result); } //标准日期格式(包括单个数字的日期时间) diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/FastDateFormat.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/FastDateFormat.java index ffd02f2df..6a832765d 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/FastDateFormat.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/FastDateFormat.java @@ -12,6 +12,7 @@ package org.dromara.hutool.core.date.format; +import org.dromara.hutool.core.date.DateException; import org.dromara.hutool.core.date.DatePattern; import org.dromara.hutool.core.date.format.parser.FastDateParser; import org.dromara.hutool.core.date.format.parser.PositionDateParser; @@ -344,7 +345,7 @@ public class FastDateFormat extends Format implements PositionDateParser, DatePr // ----------------------------------------------------------------------- Parsing @Override - public Date parse(final String source) throws ParseException { + public Date parse(final String source) throws DateException { return parser.parse(source); } @@ -360,7 +361,7 @@ public class FastDateFormat extends Format implements PositionDateParser, DatePr @Override public Object parseObject(final String source, final ParsePosition pos) { - return parser.parseObject(source, pos); + return parser.parse(source, pos); } // ----------------------------------------------------------------------- Accessors diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/GlobalCustomFormat.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/GlobalCustomFormat.java index db6c6b234..767e49475 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/GlobalCustomFormat.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/GlobalCustomFormat.java @@ -47,8 +47,8 @@ public class GlobalCustomFormat { parserMap = new SafeConcurrentHashMap<>(); // Hutool预设的几种自定义格式 - putFormatter(FORMAT_SECONDS, (date) -> String.valueOf(Math.floorDiv(date.getTime(), 1000))); - putParser(FORMAT_SECONDS, (dateStr) -> DateUtil.date(Math.multiplyExact(Long.parseLong(dateStr.toString()), 1000))); + putFormatter(FORMAT_SECONDS, (date) -> String.valueOf(Math.floorDiv(date.getTime(), 1000L))); + putParser(FORMAT_SECONDS, (dateStr) -> DateUtil.date(Math.multiplyExact(Long.parseLong(dateStr.toString()), 1000L))); putFormatter(FORMAT_MILLISECONDS, (date) -> String.valueOf(date.getTime())); putParser(FORMAT_MILLISECONDS, (dateStr) -> DateUtil.date(Long.parseLong(dateStr.toString()))); diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/DateParser.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/DateParser.java index 1f12296ca..c47fa0e90 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/DateParser.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/DateParser.java @@ -12,6 +12,7 @@ package org.dromara.hutool.core.date.format.parser; +import org.dromara.hutool.core.date.DateException; import org.dromara.hutool.core.date.format.DateBasic; import java.text.ParseException; @@ -29,19 +30,7 @@ public interface DateParser extends DateBasic{ * * @param source 被解析的日期字符串 * @return {@link Date}对象 - * @throws ParseException 转换异常,被转换的字符串格式错误。 + * @throws DateException 转换异常,被转换的字符串格式错误。 */ - Date parse(String source) throws ParseException; - - /** - * 将日期字符串解析并转换为 {@link Date} 对象
- * - * @param source 被解析的日期字符串 - * @return {@link Date}对象 - * @throws ParseException if the beginning of the specified string cannot be parsed. - * @see java.text.DateFormat#parseObject(String) - */ - default Object parseObject(final String source) throws ParseException { - return parse(source); - } + Date parse(String source) throws DateException; } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/FastDateParser.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/FastDateParser.java index 44d715cc2..b5809c2ca 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/FastDateParser.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/FastDateParser.java @@ -12,6 +12,7 @@ package org.dromara.hutool.core.date.format.parser; +import org.dromara.hutool.core.date.DateException; import org.dromara.hutool.core.date.format.FastDateFormat; import org.dromara.hutool.core.date.format.FastDatePrinter; import org.dromara.hutool.core.date.format.SimpleDateBasic; @@ -20,21 +21,8 @@ import org.dromara.hutool.core.map.SafeConcurrentHashMap; import java.io.IOException; import java.io.ObjectInputStream; import java.text.DateFormatSymbols; -import java.text.ParseException; import java.text.ParsePosition; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.ListIterator; -import java.util.Locale; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.TimeZone; -import java.util.TreeSet; +import java.util.*; import java.util.concurrent.ConcurrentMap; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -236,16 +224,16 @@ public class FastDateParser extends SimpleDateBasic implements PositionDateParse } @Override - public Date parse(final String source) throws ParseException { + public Date parse(final String source) throws DateException { final ParsePosition pp = new ParsePosition(0); final Date date = parse(source, pp); if (date == null) { // Add a note re supported date range if (locale.equals(JAPANESE_IMPERIAL)) { - throw new ParseException("(The " + locale + " locale does not support dates before 1868 AD)\n" + - "Unparseable date: \"" + source, pp.getErrorIndex()); + throw new DateException("(The " + locale + " locale does not support dates before 1868 AD)\n" + + "Unparseable date: \"" + source, pp.getErrorIndex()); } - throw new ParseException("Unparseable date: " + source, pp.getErrorIndex()); + throw new DateException("Unparseable date: " + source, pp.getErrorIndex()); } return date; } @@ -367,16 +355,6 @@ public class FastDateParser extends SimpleDateBasic implements PositionDateParse this.pattern = Pattern.compile(regex); } - /** - * Is this field a number? The default implementation returns false. - * - * @return true, if field is a number - */ - @Override - boolean isNumber() { - return false; - } - @Override boolean parse(final FastDateParser parser, final Calendar calendar, final String source, final ParsePosition pos, final int maxWidth) { final Matcher matcher = pattern.matcher(source.substring(pos.getIndex())); @@ -507,11 +485,6 @@ public class FastDateParser extends SimpleDateBasic implements PositionDateParse this.formatField = formatField; } - @Override - boolean isNumber() { - return false; - } - @Override boolean parse(final FastDateParser parser, final Calendar calendar, final String source, final ParsePosition pos, final int maxWidth) { for (int idx = 0; idx < formatField.length(); ++idx) { diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/ISO8601DateParser.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/ISO8601DateParser.java index 404c64e04..607bd3bf7 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/ISO8601DateParser.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/ISO8601DateParser.java @@ -49,7 +49,7 @@ public class ISO8601DateParser extends DefaultDateBasic implements PredicateDate } @Override - public DateTime parse(String source) { + public DateTime parse(String source) throws DateException{ final int length = source.length(); if (StrUtil.contains(source, 'Z')) { if (length == DatePattern.UTC_PATTERN.length() - 4) { diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/NormalDateParser.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/NormalDateParser.java index 68c7d90ac..ca8c1c10b 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/NormalDateParser.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/NormalDateParser.java @@ -52,7 +52,7 @@ public class NormalDateParser extends DefaultDateBasic implements PredicateDateP } @Override - public DateTime parse(String source) { + public DateTime parse(String source) throws DateException{ final int colonCount = StrUtil.count(source, CharUtil.COLON); switch (colonCount) { case 0: diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/PositionDateParser.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/PositionDateParser.java index ccedadc0e..b891a9b88 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/PositionDateParser.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/PositionDateParser.java @@ -47,16 +47,4 @@ public interface PositionDateParser extends DateParser { * @throws IllegalArgumentException when Calendar has been set to be not lenient, and a parsed field is out of range. */ boolean parse(String source, ParsePosition pos, Calendar calendar); - - /** - * 根据 {@link ParsePosition} 给定将日期字符串解析并转换为 {@link Date} 对象
- * - * @param source A {@code String} whose beginning should be parsed. - * @param pos the parse position - * @return a {@code java.util.Date} object - * @see java.text.DateFormat#parseObject(String, ParsePosition) - */ - default Object parseObject(final String source, final ParsePosition pos) { - return parse(source, pos); - } } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/PredicateDateParser.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/PredicateDateParser.java index 20b4dbba8..116f33100 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/PredicateDateParser.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/PredicateDateParser.java @@ -3,7 +3,8 @@ package org.dromara.hutool.core.date.format.parser; import java.util.function.Predicate; /** - * 通过判断字符串的匹配,解析为日期 + * 通过判断字符串的匹配,解析为日期
+ * 通过实现{@link #test(Object)}方法判断字符串是否符合此解析器的规则,如果符合,则调用{@link #parse(String)}完成解析。 * * @author looly * @since 6.0.0 diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/RegisterDateParser.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/RegisterDateParser.java new file mode 100644 index 000000000..7c1c03cc5 --- /dev/null +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/RegisterDateParser.java @@ -0,0 +1,68 @@ +package org.dromara.hutool.core.date.format.parser; + +import org.dromara.hutool.core.collection.ListUtil; +import org.dromara.hutool.core.date.DateException; +import org.dromara.hutool.core.date.format.DefaultDateBasic; + +import java.util.Date; +import java.util.List; + +/** + * 基于注册的日期解析器,通过遍历列表,找到合适的解析器,然后解析为日期
+ * 默认的,可以调用{@link #INSTANCE}使用全局的解析器,亦或者通过构造自定义独立的注册解析器 + * + * @author looly + * @since 6.0.0 + */ +public class RegisterDateParser extends DefaultDateBasic implements DateParser { + private static final long serialVersionUID = 1L; + + /** + * 单例 + */ + public static final RegisterDateParser INSTANCE = new RegisterDateParser(); + + private final List parserList; + + /** + * 构造 + */ + public RegisterDateParser() { + parserList = ListUtil.of( + // 纯数字形式 + PureDateParser.INSTANCE, + // HH:mm:ss 或者 HH:mm 时间格式匹配单独解析 + TimeParser.INSTANCE, + // JDK的Date对象toString默认格式,类似于: + // Tue Jun 4 16:25:15 +0800 2019 + // Thu May 16 17:57:18 GMT+08:00 2019 + // Wed Aug 01 00:00:00 CST 2012 + CSTDateParser.INSTANCE, + // ISO8601标准时间 + // yyyy-MM-dd'T'HH:mm:ss'Z' + // yyyy-MM-dd'T'HH:mm:ss+0800 + ISO8601DateParser.INSTANCE + ); + } + + @Override + public Date parse(final String source) throws DateException { + return parserList + .stream() + .filter(predicateDateParser -> predicateDateParser.test(source)) + .findFirst() + .map(predicateDateParser -> predicateDateParser.parse(source)).orElse(null); + } + + /** + * 注册自定义的{@link PredicateDateParser}
+ * 通过此方法,用户可以自定义日期字符串的匹配和解析,通过循环匹配,找到合适的解析器,解析之。 + * + * @param dateParser {@link PredicateDateParser} + * @return this + */ + public RegisterDateParser register(final PredicateDateParser dateParser) { + this.parserList.add(dateParser); + return this; + } +} diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/package-info.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/package-info.java index 148b8fde8..7d9b96a1d 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/package-info.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/package-info.java @@ -11,9 +11,14 @@ */ /** - * 提供日期解析相关封装 + * 提供日期解析相关封装,主要包括: + *
+ *                  DateParser
+ *                   /    \
+ *     FastDateParser     RegisterDateParser
+ *   (根据日期格式解析)   (根据注册的模式匹配解析)
+ * 
* * @author looly - * */ package org.dromara.hutool.core.date.format.parser;