This commit is contained in:
Looly 2024-06-28 12:01:31 +08:00
parent 85fac17eac
commit 6a5ff924ee
2 changed files with 62 additions and 16 deletions

View File

@ -29,36 +29,44 @@ public class GlobalRegexDateParser {
private static final String dayRegex = "(?<day>\\d{1,2})(?:th)?";
// 周的正则匹配Mon, Tue, Wed, Thu, Fri, Sat, Sun Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
// 日期中一般出现在头部可选
private static final String weekRegex = "(?<week>[mwfts][oeruha][ndieut](\\w{3,6})?\\W+)?";
private static final String weekRegexWithSuff = "(?<week>[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+(?<hour>\\d{1,2})" +
private static final String timeRegexWithPre = "(" +
"\\W+(at\\s)?(?<hour>\\d{1,2})" +
":(?<minute>\\d{1,2})" +
"(:(?<second>\\d{1,2}))?" +
"(?:[.,](?<ns>\\d{1,9}))?(?<zero>z)?" +
"(\\s?(?<m>[ap]m))?" +
")?";
// 时区类似 +08:00 +0800 +08可选
private static final String zoneOffsetRegex = "(\\s?(?<zoneOffset>[-+]\\d{1,2}:?(?:\\d{2})?))?";
private static final String zoneOffsetRegexWithPre = "(\\s?(?<zoneOffset>[-+]\\d{1,2}:?(?:\\d{2})?))?";
// 时区名称类似 CST UTC (CST)可选
private static final String zoneNameRegex = "(\\s[(]?(?<zoneName>[a-z ]+)[)]?)?";
private static final String zoneNameRegexWithPre = "(\\s[(]?(?<zoneName>[a-z ]+)[)]?)?";
private static final String zoneNameIgnoreRegexWithPre = "(\\s[(]?(?<zoneNameIgnore>[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:515: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:515: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
);
}

View File

@ -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) {