diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/GlobalRegexDateParser.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/GlobalRegexDateParser.java index a0ccdd1e3..ee7886cfb 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/GlobalRegexDateParser.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/GlobalRegexDateParser.java @@ -29,36 +29,44 @@ public class GlobalRegexDateParser { private static final String dayRegex = "(?\\d{1,2})(?:th)?"; // 周的正则,匹配:Mon, Tue, Wed, Thu, Fri, Sat, Sun,或 Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday // 日期中一般出现在头部,可选 - private static final String weekRegex = "(?[mwfts][oeruha][ndieut](\\w{3,6})?\\W+)?"; + private static final String weekRegexWithSuff = "(?[mwfts][oeruha][ndieut](\\w{3,6})?\\W+)?"; // hh:mm:ss.SSSSZ hh:mm:ss.SSSS hh:mm:ss hh:mm - private static final String timeRegex = "(" + - "\\W+(?\\d{1,2})" + + private static final String timeRegexWithPre = "(" + + "\\W+(at\\s)?(?\\d{1,2})" + ":(?\\d{1,2})" + "(:(?\\d{1,2}))?" + "(?:[.,](?\\d{1,9}))?(?z)?" + "(\\s?(?[ap]m))?" + ")?"; // 时区,类似: +08:00 +0800 +08,可选 - private static final String zoneOffsetRegex = "(\\s?(?[-+]\\d{1,2}:?(?:\\d{2})?))?"; + private static final String zoneOffsetRegexWithPre = "(\\s?(?[-+]\\d{1,2}:?(?:\\d{2})?))?"; // 时区名称,类似: CST UTC (CST),可选 - private static final String zoneNameRegex = "(\\s[(]?(?[a-z ]+)[)]?)?"; + private static final String zoneNameRegexWithPre = "(\\s[(]?(?[a-z ]+)[)]?)?"; + private static final String zoneNameIgnoreRegexWithPre = "(\\s[(]?(?[a-z ]+)[)]?)?"; private static final RegexDateParser PARSER; static { // 月开头,类似:May 8 final String dateRegexMonthFirst = monthRegex + "\\W+" + dayRegex; + // 日开头,类似:02-Jan + final String dateRegexDayFirst = dayRegex + "\\W+" + monthRegex; + // 时区拼接,类似: + // GMT+0100 (GMT Daylight Time) + // +0200 (CEST) + // GMT+0100 + // MST + final String zoneRegex = zoneNameRegexWithPre + zoneOffsetRegexWithPre + zoneNameIgnoreRegexWithPre; PARSER = RegexDateParser.of( // 年开头 - //月在前,类似:May 8, 2009,时间部分可选,类似:5:57:51,5:57:51 +08:00 - weekRegex + dateRegexMonthFirst + "\\W+" + yearRegex + timeRegex + zoneOffsetRegex, - // 年在最后,类似:Mon Jan 2 15:04:05 MST 2006 - weekRegex + dateRegexMonthFirst + timeRegex + zoneNameRegex + zoneOffsetRegex + "\\W+" + yearRegex - - // 日开头 - + //【周月日年时】类似:May 8, 2009,时间部分可选,类似:5:57:51,5:57:51 +08:00 + weekRegexWithSuff + dateRegexMonthFirst + "\\W+" + yearRegex + timeRegexWithPre + zoneRegex, + //【周月日时年】类似:Mon Jan 2 15:04:05 MST 2006 + weekRegexWithSuff + dateRegexMonthFirst + timeRegexWithPre + zoneRegex + "\\W+" + yearRegex, + //【周日月年时】类似:Monday, 02-Jan-06 15:04:05 MST + weekRegexWithSuff + dateRegexDayFirst + "\\W+" + yearRegex + timeRegexWithPre + zoneRegex ); } diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/date/format/parser/GlobalRegexDateParserTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/date/format/parser/GlobalRegexDateParserTest.java index 926440b11..9e164d101 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/date/format/parser/GlobalRegexDateParserTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/date/format/parser/GlobalRegexDateParserTest.java @@ -7,10 +7,24 @@ import java.util.Date; import static org.junit.jupiter.api.Assertions.assertEquals; +/** + * https://gitee.com/dromara/hutool/issues/I8IUTB + */ public class GlobalRegexDateParserTest { @Test - void parseMonthFirstTest() { + void parseMonthDayYearTest() { + assertParse("1970-10-07 00:00:00", "oct 7, 1970"); + assertParse("1970-10-07 00:00:00", "oct 7, '70"); + assertParse("1970-10-07 00:00:00", "oct. 7, 1970"); + assertParse("1970-10-07 00:00:00", "oct. 7, 70"); + assertParse("1970-10-07 00:00:00", "October 7, 1970"); + assertParse("1970-10-07 00:00:00", "October 7th, 1970"); + assertParse("1970-10-07 00:00:00", "October 7th, 1970"); + } + + @Test + void parseMonthDayYearTimeTest() { assertParse("2009-05-08 05:57:51", "May 8, 2009 5:57:51"); assertParse("2009-05-08 17:57:51", "May 8, 2009 5:57:51 PM"); assertParse("2009-05-08 17:57:51", "May 8, 2009 5:57:51 pm"); @@ -22,20 +36,44 @@ public class GlobalRegexDateParserTest { assertParse("2009-05-08 00:00:00", "May 8th, 2009"); assertParse("2009-05-08 00:00:00", "May 8th, 09"); assertParse("2009-05-08 00:00:00", "may. 8th, 09"); + assertParse("2012-09-17 10:09:00", "September 17, 2012 10:09am"); + assertParse("2012-09-18 02:09:00", "September 17, 2012 at 10:09am PST-08"); + assertParse("2012-09-17 10:10:09", "September 17, 2012, 10:10:09"); } @Test - void parseWeekFirstTest() { + void parseWeekMonthDayYearTimeTest() { assertParse("2006-01-02 15:04:05", "Mon Jan 2, 2006 15:04:05"); assertParse("2006-01-02 15:04:05", "Mon Jan 2 2006 15:04:05"); + assertParse("2015-07-04 01:04:07", "Fri Jul 03 2015 18:04:07 GMT+0100 (GMT Daylight Time)"); } @Test - void parseWeekFirstYearLastTest() { + void parseWeekMonthDayTimeYearTest() { assertParse("2006-01-02 15:04:05", "Mon Jan 2 15:04:05 2006"); assertParse("2006-01-02 15:04:05", "Mon Jan 2 15:04:05 MST 2006"); assertParse("2006-01-03 06:04:05", "Mon Jan 02 15:04:05 -0700 2006"); - //assertParse("2006-01-03 06:04:05", "Monday, 02-Jan-06 15:04:05 MST"); + assertParse("2015-08-10 22:44:11", "Mon Aug 10 15:44:11 UTC+0100 2015"); + } + + @Test + void parseWeekDayMonthYearTimeTest() { + assertParse("2006-01-02 15:04:05", "Monday, 02-Jan-06 15:04:05 MST"); + assertParse("2006-01-02 15:04:05", "Mon, 02 Jan 2006 15:04:05 MST"); + assertParse("2017-07-11 22:28:13", "Tue, 11 Jul 2017 16:28:13 +0200"); + assertParse("2017-07-11 22:28:13", "Tue, 11 Jul 2017 16:28:13 +0200 (CEST)"); + assertParse("2006-01-03 06:04:05", "Mon, 02 Jan 2006 15:04:05 -0700"); + assertParse("2018-01-05 01:53:36", "Thu, 4 Jan 2018 17:53:36 +0000"); + } + + @Test + void parseDayMonthYear() { + assertParse("2006-02-12 19:17:00", "12 Feb 2006, 19:17"); + assertParse("2006-02-12 19:17:00", "12 Feb 2006 19:17"); + assertParse("1970-10-07 00:00:00", "7 oct 70"); + assertParse("1970-10-07 00:00:00", "7 oct 1970"); + assertParse("2013-02-03 00:00:00", "03 February 2013"); + assertParse("2013-07-01 00:00:00", "1 July 2013"); } private static void assertParse(final String dateStr, final String dateStrToParse) {