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 001c1b11c..cb9aa732f 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
@@ -2,6 +2,7 @@ package cn.hutool.core.date;
import cn.hutool.core.comparator.CompareUtil;
import cn.hutool.core.convert.NumberChineseFormatter;
+import cn.hutool.core.date.format.DateParser;
import cn.hutool.core.date.format.FastDateParser;
import cn.hutool.core.date.format.GlobalCustomFormat;
import cn.hutool.core.util.ObjectUtil;
@@ -695,4 +696,21 @@ public class CalendarUtil {
throw new DateException("Unable to parse the date: {}", str);
}
+
+ /**
+ * 使用指定{@link DateParser}解析字符串为{@link Calendar}
+ *
+ * @param str 日期字符串
+ * @param lenient 是否宽容模式
+ * @param parser {@link DateParser}
+ * @return 解析后的 {@link Calendar},解析失败返回{@code null}
+ * @since 5.7.14
+ */
+ public static Calendar parse(CharSequence str, boolean lenient, DateParser parser) {
+ final Calendar calendar = Calendar.getInstance(parser.getTimeZone(), parser.getLocale());
+ calendar.clear();
+ calendar.setLenient(lenient);
+
+ return parser.parse(StrUtil.str(str), new ParsePosition(0), calendar) ? calendar : null;
+ }
}
diff --git a/hutool-core/src/main/java/cn/hutool/core/date/DateTime.java b/hutool-core/src/main/java/cn/hutool/core/date/DateTime.java
index 1fb76da0f..cdb79e618 100644
--- a/hutool-core/src/main/java/cn/hutool/core/date/DateTime.java
+++ b/hutool-core/src/main/java/cn/hutool/core/date/DateTime.java
@@ -287,7 +287,7 @@ public class DateTime extends Date {
* @see DatePattern
*/
public DateTime(CharSequence dateStr, DateParser dateParser) {
- this(parse(dateStr, dateParser), dateParser.getTimeZone());
+ this(parse(dateStr, dateParser));
}
// -------------------------------------------------------------------- Constructor end
@@ -1019,14 +1019,15 @@ public class DateTime extends Date {
* @param parser {@link FastDateFormat}
* @return {@link Date}
*/
- private static Date parse(CharSequence dateStr, DateParser parser) {
+ private static Calendar parse(CharSequence dateStr, DateParser parser) {
Assert.notNull(parser, "Parser or DateFromat must be not null !");
Assert.notBlank(dateStr, "Date String must be not blank !");
- try {
- return parser.parse(dateStr.toString());
- } catch (Exception e) {
- throw new DateException("Parse [{}] with format [{}] error!", dateStr, parser.getPattern(), e);
+
+ final Calendar calendar = CalendarUtil.parse(dateStr, true, parser);
+ if (null == calendar) {
+ throw new DateException("Parse [{}] with format [{}] error!", dateStr, parser.getPattern());
}
+ return calendar;
}
/**
diff --git a/hutool-core/src/main/java/cn/hutool/core/date/format/DateParser.java b/hutool-core/src/main/java/cn/hutool/core/date/format/DateParser.java
index db4f520d7..5668f579f 100644
--- a/hutool-core/src/main/java/cn/hutool/core/date/format/DateParser.java
+++ b/hutool-core/src/main/java/cn/hutool/core/date/format/DateParser.java
@@ -33,8 +33,8 @@ public interface DateParser extends DateBasic{
Date parse(String source, ParsePosition pos);
/**
- * 根据给定格式转换日期字符串
- * Updates the Calendar with parsed fields. Upon success, the ParsePosition index is updated to indicate how much of the source text was consumed.
+ * 根据给定格式更新{@link Calendar}
+ * Upon success, the ParsePosition index is updated to indicate how much of the source text was consumed.
* Not all source text needs to be consumed.
* Upon parse failure, ParsePosition error index is updated to the offset of the source text which does not match the supplied format.
*
@@ -49,20 +49,24 @@ public interface DateParser extends DateBasic{
/**
* 将日期字符串解析并转换为 {@link Date} 对象
*
- * @param source A String
whose beginning should be parsed.
- * @return a java.util.Date
object
+ * @param source A {@code String} whose beginning should be parsed.
+ * @return a {@code java.util.Date} object
* @throws ParseException if the beginning of the specified string cannot be parsed.
* @see java.text.DateFormat#parseObject(String)
*/
- Object parseObject(String source) throws ParseException;
+ default Object parseObject(String source) throws ParseException{
+ return parse(source);
+ }
/**
* 根据 {@link ParsePosition} 给定将日期字符串解析并转换为 {@link Date} 对象
*
- * @param source A String
whose beginning should be parsed.
+ * @param source A {@code String} whose beginning should be parsed.
* @param pos the parse position
- * @return a java.util.Date
object
+ * @return a {@code java.util.Date} object
* @see java.text.DateFormat#parseObject(String, ParsePosition)
*/
- Object parseObject(String source, ParsePosition pos);
+ default Object parseObject(String source, ParsePosition pos){
+ return parse(source, pos);
+ }
}
diff --git a/hutool-core/src/main/java/cn/hutool/core/date/format/FastDateParser.java b/hutool-core/src/main/java/cn/hutool/core/date/format/FastDateParser.java
index 88f6385f5..e0ddfbc84 100644
--- a/hutool-core/src/main/java/cn/hutool/core/date/format/FastDateParser.java
+++ b/hutool-core/src/main/java/cn/hutool/core/date/format/FastDateParser.java
@@ -220,18 +220,14 @@ public class FastDateParser extends AbstractDateBasic implements DateParser {
}
@Override
- public Object parseObject(final String source) throws ParseException {
- return parse(source);
- }
-
- @Override
- public Date parse(final String source) throws ParseException {
+ public Date parse(String source) throws ParseException {
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 ParseException("(The " + locale + " locale does not support dates before 1868 AD)\n" +
+ "Unparseable date: \"" + source, pp.getErrorIndex());
}
throw new ParseException("Unparseable date: " + source, pp.getErrorIndex());
}
@@ -239,12 +235,7 @@ public class FastDateParser extends AbstractDateBasic implements DateParser {
}
@Override
- public Object parseObject(final String source, final ParsePosition pos) {
- return parse(source, pos);
- }
-
- @Override
- public Date parse(final String source, final ParsePosition pos) {
+ public Date parse(String source, ParsePosition pos) {
// timing tests indicate getting new instance is 19% faster than cloning
final Calendar cal = Calendar.getInstance(timeZone, locale);
cal.clear();
@@ -253,12 +244,12 @@ public class FastDateParser extends AbstractDateBasic implements DateParser {
}
@Override
- public boolean parse(final String source, final ParsePosition pos, final Calendar calendar) {
+ public boolean parse(String source, ParsePosition pos, Calendar calendar) {
final ListIterator lt = patterns.listIterator();
while (lt.hasNext()) {
final StrategyAndWidth strategyAndWidth = lt.next();
final int maxWidth = strategyAndWidth.getMaxWidth(lt);
- if (!strategyAndWidth.strategy.parse(this, calendar, source, pos, maxWidth)) {
+ if (false == strategyAndWidth.strategy.parse(this, calendar, source, pos, maxWidth)) {
return false;
}
}
@@ -500,9 +491,6 @@ public class FastDateParser extends AbstractDateBasic implements DateParser {
this.formatField = formatField;
}
- /**
- * {@inheritDoc}
- */
@Override
boolean isNumber() {
return false;
@@ -575,9 +563,6 @@ public class FastDateParser extends AbstractDateBasic implements DateParser {
this.field = field;
}
- /**
- * {@inheritDoc}
- */
@Override
boolean isNumber() {
return true;
@@ -637,9 +622,6 @@ public class FastDateParser extends AbstractDateBasic implements DateParser {
}
private static final Strategy ABBREVIATED_YEAR_STRATEGY = new NumberStrategy(Calendar.YEAR) {
- /**
- * {@inheritDoc}
- */
@Override
int modify(final FastDateParser parser, final int iValue) {
return iValue < 100 ? parser.adjustYear(iValue) : iValue;
@@ -726,9 +708,6 @@ public class FastDateParser extends AbstractDateBasic implements DateParser {
createPattern(sb);
}
- /**
- * {@inheritDoc}
- */
@Override
void setCalendar(final FastDateParser parser, final Calendar cal, final String value) {
if (value.charAt(0) == '+' || value.charAt(0) == '-') {
@@ -759,9 +738,6 @@ public class FastDateParser extends AbstractDateBasic implements DateParser {
createPattern(pattern);
}
- /**
- * {@inheritDoc}
- */
@Override
void setCalendar(final FastDateParser parser, final Calendar cal, final String value) {
if (Objects.equals(value, "Z")) {
diff --git a/hutool-core/src/test/java/cn/hutool/core/date/CalendarUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/date/CalendarUtilTest.java
index 79920e5e6..63e7fc7f9 100644
--- a/hutool-core/src/test/java/cn/hutool/core/date/CalendarUtilTest.java
+++ b/hutool-core/src/test/java/cn/hutool/core/date/CalendarUtilTest.java
@@ -4,15 +4,26 @@ import org.junit.Assert;
import org.junit.Test;
import java.util.Calendar;
+import java.util.Objects;
public class CalendarUtilTest {
@Test
public void formatChineseDate(){
- Calendar calendar = DateUtil.parse("2018-02-24 12:13:14").toCalendar();
+ Calendar calendar = Objects.requireNonNull(DateUtil.parse("2018-02-24 12:13:14")).toCalendar();
final String chineseDate = CalendarUtil.formatChineseDate(calendar, false);
Assert.assertEquals("二〇一八年二月二十四日", chineseDate);
final String chineseDateTime = CalendarUtil.formatChineseDate(calendar, true);
Assert.assertEquals("二〇一八年二月二十四日一十二时一十三分一十四秒", chineseDateTime);
}
+
+ @Test(expected = IllegalArgumentException.class)
+ public void parseTest(){
+ final Calendar calendar = CalendarUtil.parse("2021-09-27 00:00:112323", false,
+ DatePattern.NORM_DATETIME_FORMAT);
+
+ // https://github.com/dromara/hutool/issues/1849
+ // 在使用严格模式时,秒不正确,抛出异常
+ DateUtil.date(calendar);
+ }
}
diff --git a/hutool-core/src/test/java/cn/hutool/core/date/DateTimeTest.java b/hutool-core/src/test/java/cn/hutool/core/date/DateTimeTest.java
index 3a0724cc1..bf856d611 100644
--- a/hutool-core/src/test/java/cn/hutool/core/date/DateTimeTest.java
+++ b/hutool-core/src/test/java/cn/hutool/core/date/DateTimeTest.java
@@ -1,5 +1,6 @@
package cn.hutool.core.date;
+import cn.hutool.core.lang.Console;
import org.junit.Assert;
import org.junit.Test;
@@ -131,4 +132,11 @@ public class DateTimeTest {
//跨年的周返回的总是1
Assert.assertEquals(1, date.weekOfYear());
}
+
+ @Test
+ public void ofTest(){
+ String a = "2021-09-27 00:00:99";
+ final DateTime dateTime = new DateTime(a, DatePattern.NORM_DATETIME_FORMAT);
+ Console.log(dateTime);
+ }
}
diff --git a/hutool-core/src/test/java/cn/hutool/core/text/csv/CsvReaderTest.java b/hutool-core/src/test/java/cn/hutool/core/text/csv/CsvReaderTest.java
index 908f1c5c5..d21bf9c3b 100644
--- a/hutool-core/src/test/java/cn/hutool/core/text/csv/CsvReaderTest.java
+++ b/hutool-core/src/test/java/cn/hutool/core/text/csv/CsvReaderTest.java
@@ -183,4 +183,12 @@ public class CsvReaderTest {
Assert.assertEquals("456", row.get(1));
Assert.assertEquals("'789;0'abc", row.get(2));
}
+
+ @Test
+ public void readDisableCommentTest(){
+ final CsvReader reader = CsvUtil.getReader(CsvReadConfig.defaultConfig().disableComment());
+ final CsvData read = reader.read(ResourceUtil.getUtf8Reader("test.csv"));
+ final CsvRow row = read.getRow(0);
+ Assert.assertEquals("# 这是一行注释,读取时应忽略", row.get(0));
+ }
}