diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/TemporalAccessorConverter.java b/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/TemporalAccessorConverter.java index 40f546d4f..85a6f59d4 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/TemporalAccessorConverter.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/TemporalAccessorConverter.java @@ -138,7 +138,7 @@ public class TemporalAccessorConverter extends AbstractConverter { } final Instant instant; - ZoneId zoneId = null; + final ZoneId zoneId; if (null != this.format) { final DateTimeFormatter formatter = TimeUtil.ofPattern(this.format); diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/CalendarUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/CalendarUtil.java index 2a6fedfac..9710b42e1 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/CalendarUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/CalendarUtil.java @@ -792,19 +792,8 @@ public class CalendarUtil { */ public static Calendar parse(final CharSequence str, final PositionDateParser parser, final boolean lenient) throws DateException{ - Assert.notBlank(str, "Date str must be not blank!"); Assert.notNull(parser, "Parser must be not null!"); - final Calendar calendar = Calendar.getInstance(parser.getTimeZone(), parser.getLocale()); - calendar.clear(); - calendar.setLenient(lenient); - - final ParsePosition position = new ParsePosition(0); - if (parser.parse(str.toString(), position, calendar)) { - return calendar; - } - - throw new DateException("Parse [{}] with format [{}] error, at: {}", - str, parser.getPattern(), position.getErrorIndex()); + return parser.parseCalendar(str, null, lenient); } // endregion diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/DateTime.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/DateTime.java index 41f556c5d..73be06055 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/DateTime.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/DateTime.java @@ -16,15 +16,14 @@ package org.dromara.hutool.core.date; +import org.dromara.hutool.core.date.format.DateFormatManager; import org.dromara.hutool.core.date.format.DatePrinter; import org.dromara.hutool.core.date.format.FastDateFormat; -import org.dromara.hutool.core.date.format.DateFormatManager; import org.dromara.hutool.core.date.format.parser.DateParser; import org.dromara.hutool.core.date.format.parser.PositionDateParser; import org.dromara.hutool.core.lang.Assert; import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.util.ObjUtil; -import org.dromara.hutool.core.util.SystemUtil; import java.text.DateFormat; import java.text.SimpleDateFormat; @@ -297,9 +296,7 @@ public class DateTime extends Date { * @see DateFormatPool */ public DateTime(final CharSequence dateStr, final String format) { - this(DateFormatManager.getInstance().isCustomFormat(format) - ? DateFormatManager.getInstance().parse(dateStr, format) - : parse(dateStr, DateUtil.newSimpleFormat(format))); + this(parse(dateStr, format)); } /** @@ -332,7 +329,7 @@ public class DateTime extends Date { * @see DateFormatPool */ public DateTime(final CharSequence dateStr, final PositionDateParser dateParser) { - this(dateStr, dateParser, SystemUtil.getBoolean(SystemUtil.HUTOOL_DATE_LENIENT, false)); + this(dateStr, dateParser, DateUtil.isGlobalLenient()); } /** @@ -1076,6 +1073,20 @@ public class DateTime extends Date { } // -------------------------------------------------------------------- toString end + /** + * 转换字符串为Date + * + * @param dateStr 日期字符串 + * @param format 格式字符串 + * @return {@link Date} + */ + private static Date parse(final CharSequence dateStr, final String format) { + final DateFormatManager formatManager = DateFormatManager.getInstance(); + return formatManager.isCustomFormat(format) + ? formatManager.parse(dateStr, format) + : parse(dateStr, DateUtil.newSimpleFormat(format)); + } + /** * 转换字符串为Date * @@ -1098,21 +1109,6 @@ public class DateTime extends Date { } } - /** - * 转换字符串为Date - * - * @param dateStr 日期字符串 - * @param parser {@link FastDateFormat} - * @param lenient 是否宽容模式 - * @return {@link Calendar} - */ - private static Calendar parse(final CharSequence dateStr, final PositionDateParser parser, final boolean lenient) { - final Calendar calendar = CalendarUtil.parse(dateStr, parser, lenient); - //noinspection MagicConstant - calendar.setFirstDayOfWeek(Week.MONDAY.getValue()); - return calendar; - } - /** * 设置日期时间 * @@ -1123,4 +1119,19 @@ public class DateTime extends Date { super.setTime(time); return this; } + + /** + * 转换字符串为Date + * + * @param dateStr 日期字符串 + * @param parser {@link FastDateFormat} + * @param lenient 是否宽容模式 + * @return {@link Calendar} + */ + private static Calendar parse(final CharSequence dateStr, final PositionDateParser parser, final boolean lenient) { + final Calendar calendar = parser.parseCalendar(dateStr, null, lenient); + //noinspection MagicConstant + calendar.setFirstDayOfWeek(Week.MONDAY.getValue()); + return calendar; + } } 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 7f6ce3eb2..09ab33b61 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 @@ -743,24 +743,6 @@ public class DateUtil { return new DateTime(dateStr, format); } - /** - * 将特定格式的日期转换为Date对象 - * - * @param dateStr 特定格式的日期 - * @param format 格式,例如yyyy-MM-dd - * @param locale 区域信息 - * @return 日期对象 - * @since 4.5.18 - */ - public static DateTime parse(final CharSequence dateStr, final String format, final Locale locale) { - final DateFormatManager formatManager = DateFormatManager.getInstance(); - if (formatManager.isCustomFormat(format)) { - // 自定义格式化器忽略Locale - return new DateTime(formatManager.parse(dateStr, format)); - } - return new DateTime(dateStr, DateUtil.newSimpleFormat(format, locale, null)); - } - /** * 通过给定的日期格式解析日期时间字符串。
* 传入的日期格式会逐个尝试,直到解析成功,返回{@link DateTime}对象,否则抛出{@link DateException}异常。 @@ -1935,6 +1917,16 @@ public class DateUtil { return java.time.Month.of(month).length(isLeapYear); } + /** + * 获取全局参数,是否日期解析宽容模式,未定义时返回false
+ * 通过系统参数{@code hutool.date.lenient}定义 + * + * @return 是否日期解析宽容模式 + */ + public static boolean isGlobalLenient() { + return SystemUtil.getBoolean(SystemUtil.HUTOOL_DATE_LENIENT, false); + } + /** * 创建{@link SimpleDateFormat},注意此对象非线程安全!
* 此对象默认为严格格式模式,即parse时如果格式不正确会报错。 @@ -1959,8 +1951,7 @@ public class DateUtil { */ public static SimpleDateFormat newSimpleFormat(final String pattern, final Locale locale, final TimeZone timeZone) { - return newSimpleFormat(pattern, locale, timeZone, - SystemUtil.getBoolean(SystemUtil.HUTOOL_DATE_LENIENT, false)); + return newSimpleFormat(pattern, locale, timeZone, isGlobalLenient()); } /** 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 0303d7746..12328482f 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 @@ -366,11 +366,6 @@ public class FastDateFormat extends Format implements PositionDateParser, DatePr return parser.parse(source); } - @Override - public Date parse(final CharSequence source, final ParsePosition pos) { - return parser.parse(source, pos); - } - @Override public boolean parse(final CharSequence source, final ParsePosition pos, final Calendar calendar) { return parser.parse(source, pos, calendar); 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 dd536966d..c6184ac88 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 @@ -244,16 +244,11 @@ public class FastDateParser extends SimpleDateBasic implements PositionDateParse } @Override - public Date parse(final CharSequence source, final ParsePosition pos) { - // timing tests indicate getting new instance is 19% faster than cloning - final Calendar cal = Calendar.getInstance(timeZone, locale); - cal.clear(); + public boolean parse(final CharSequence source, ParsePosition pos, final Calendar calendar) { + if(null == pos){ + pos = new ParsePosition(0); + } - return parse(source, pos, cal) ? cal.getTime() : null; - } - - @Override - public boolean parse(final CharSequence source, final ParsePosition pos, final Calendar calendar) { final ListIterator lt = patterns.listIterator(); while (lt.hasNext()) { final StrategyAndWidth strategyAndWidth = lt.next(); 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 cee573b05..b14b7b7f1 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 @@ -16,7 +16,10 @@ package org.dromara.hutool.core.date.format.parser; +import org.dromara.hutool.core.date.DateException; +import org.dromara.hutool.core.date.DateUtil; import org.dromara.hutool.core.date.format.DateBasic; +import org.dromara.hutool.core.lang.Assert; import java.text.ParsePosition; import java.util.Calendar; @@ -26,10 +29,23 @@ import java.util.Date; * 带有{@link ParsePosition}的日期解析接口,用于解析日期字符串为 {@link Date} 对象
* Thanks to Apache Commons Lang 3.5 * - * @since 2.16.2 + * @author Looly + * @since 6.0.0 */ public interface PositionDateParser extends DateParser, DateBasic { + /** + * 根据给定格式更新{@link Calendar}
+ * 解析成功后,{@link ParsePosition#getIndex()}更新成转换到的位置
+ * 失败则{@link ParsePosition#getErrorIndex()}更新到解析失败的位置 + * + * @param source 被转换的日期字符串 + * @param pos 定义开始转换的位置,转换结束后更新转换到的位置,{@code null}表示忽略,从第一个字符开始转换 + * @param calendar 解析并更新的{@link Calendar} + * @return 解析成功返回 {@code true},否则返回{@code false} + */ + boolean parse(CharSequence source, ParsePosition pos, Calendar calendar); + /** * 将日期字符串解析并转换为 {@link Date} 对象
* 等价于 {@link java.text.DateFormat#parse(String, ParsePosition)} @@ -38,17 +54,31 @@ public interface PositionDateParser extends DateParser, DateBasic { * @param pos {@link ParsePosition} * @return {@link Date} */ - Date parse(CharSequence source, ParsePosition pos); + default Date parse(final CharSequence source, final ParsePosition pos){ + return parseCalendar(source, pos, DateUtil.isGlobalLenient()).getTime(); + } /** - * 根据给定格式更新{@link Calendar}
- * 解析成功后,{@link ParsePosition#getIndex()}更新成转换到的位置
- * 失败则{@link ParsePosition#getErrorIndex()}更新到解析失败的位置 + * 将日期字符串解析并转换为 {@link Calendar} 对象
* - * @param source 被转换的日期字符串 - * @param pos 定义开始转换的位置,转换结束后更新转换到的位置 - * @param calendar 解析并更新的{@link Calendar} - * @return 解析成功返回 {@code true},否则返回{@code false} + * @param source 日期字符串 + * @param pos {@link ParsePosition} + * @param lenient 是否宽容模式 + * @return {@link Calendar} */ - boolean parse(CharSequence source, ParsePosition pos, Calendar calendar); + default Calendar parseCalendar(final CharSequence source, final ParsePosition pos, final boolean lenient){ + Assert.notBlank(source, "Date str must be not blank!"); + + // timing tests indicate getting new instance is 19% faster than cloning + final Calendar calendar = Calendar.getInstance(getTimeZone(), getLocale()); + calendar.clear(); + calendar.setLenient(lenient); + + if (parse(source.toString(), pos, calendar)) { + return calendar; + } + + throw new DateException("Parse [{}] with format [{}] error, at: {}", + source, getPattern(), pos.getErrorIndex()); + } } 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 d20d737aa..a791d1f74 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 @@ -17,10 +17,10 @@ /** * 提供日期解析相关封装,主要包括: *
- *                  DateParser
- *                   /    \
- *     FastDateParser     RegisterDateParser
- *   (根据日期格式解析)   (根据注册的模式匹配解析)
+ *                            DateParser
+ *             /                  |                   \
+ *     FastDateParser     RegisterDateParser     RegexDateParser
+ *   (根据日期格式解析)   (根据注册的模式匹配解析) (通过预定义正则解析)
  * 
* * @author looly