support RFC2822

This commit is contained in:
Looly 2024-03-28 23:13:59 +08:00
parent 0358c3bde1
commit 054aad0a53
7 changed files with 75 additions and 10 deletions

View File

@ -13,7 +13,7 @@
package org.dromara.hutool.core.date;
import org.dromara.hutool.core.date.format.FastDateFormat;
import org.dromara.hutool.core.date.format.parser.CSTDateParser;
import org.dromara.hutool.core.date.format.parser.RFC2822DateParser;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
@ -64,7 +64,7 @@ import java.util.TimeZone;
*
* <p>
* 其中CST格式形如"Mon Aug 15 14:23:15 CST 2022",上面未包含
* 参见{@link CSTDateParser#parse(String)}{@link DateUtil#parse(String, String...)}{@link Date#toString()}进行处理
* 参见{@link RFC2822DateParser#parse(String)}{@link DateUtil#parse(String, String...)}{@link Date#toString()}进行处理
* </p>
*
* <p>
@ -288,10 +288,14 @@ public class DatePattern {
* HTTP头中日期时间格式EEE, dd MMM yyyy HH:mm:ss z
*/
public static final String HTTP_DATETIME_PATTERN = "EEE, dd MMM yyyy HH:mm:ss z";
/**
* HTTP头中日期时间格式 {@link FastDateFormat}EEE, dd MMM yyyy HH:mm:ss GMT
*/
public static final FastDateFormat HTTP_DATETIME_FORMAT_GMT = FastDateFormat.getInstance(HTTP_DATETIME_PATTERN, TimeZone.getTimeZone("GMT"), Locale.US);
/**
* HTTP头中日期时间格式 {@link FastDateFormat}EEE, dd MMM yyyy HH:mm:ss z
*/
public static final FastDateFormat HTTP_DATETIME_FORMAT = FastDateFormat.getInstance(HTTP_DATETIME_PATTERN, TimeZone.getTimeZone("GMT"), Locale.US);
public static final FastDateFormat HTTP_DATETIME_FORMAT = FastDateFormat.getInstance(HTTP_DATETIME_PATTERN, Locale.US);
/**
* JDK中日期时间格式EEE MMM dd HH:mm:ss zzz yyyy

View File

@ -650,7 +650,7 @@ public class DateUtil extends CalendarUtil {
if (null == date) {
return null;
}
return DatePattern.HTTP_DATETIME_FORMAT.format(date);
return DatePattern.HTTP_DATETIME_FORMAT_GMT.format(date);
}
/**

View File

@ -15,26 +15,32 @@ package org.dromara.hutool.core.date.format.parser;
import org.dromara.hutool.core.date.DatePattern;
import org.dromara.hutool.core.date.DateTime;
import org.dromara.hutool.core.date.format.DefaultDateBasic;
import org.dromara.hutool.core.date.format.FastDateFormat;
import org.dromara.hutool.core.text.StrUtil;
import java.util.Locale;
/**
* CST日期字符串JDK的Date对象toString默认格式解析支持格式类似于
* RFC2822日期字符串JDK的Date对象toString默认格式及HTTP消息日期解析支持格式类似于
* <pre>
* 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
* Thu, 28 Mar 2024 14:33:49 GMT
* </pre>
*
* @author looly
* @since 6.0.0
*/
public class CSTDateParser extends DefaultDateBasic implements PredicateDateParser {
public class RFC2822DateParser extends DefaultDateBasic implements PredicateDateParser {
private static final long serialVersionUID = 1L;
private static final String KEYWORDS_LOCALE_CHINA = "星期";
/**
* java.util.Date EEE MMM zzz 缩写数组
*/
private final static String[] wtb = { //
private static final String[] wtb = { //
"sun", "mon", "tue", "wed", "thu", "fri", "sat", // 星期
"jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec", // 月份
"gmt", "ut", "utc", "est", "edt", "cst", "cdt", "mst", "mdt", "pst", "pdt"// 时间标准
@ -43,7 +49,7 @@ public class CSTDateParser extends DefaultDateBasic implements PredicateDatePars
/**
* 单例对象
*/
public static CSTDateParser INSTANCE = new CSTDateParser();
public static RFC2822DateParser INSTANCE = new RFC2822DateParser();
@Override
public boolean test(final CharSequence dateStr) {
@ -52,6 +58,21 @@ public class CSTDateParser extends DefaultDateBasic implements PredicateDatePars
@Override
public DateTime parse(final String source) {
// issue#I9C2D4
if(StrUtil.contains(source, ',')){
if(StrUtil.contains(source, KEYWORDS_LOCALE_CHINA)){
// 例如星期四, 28 三月 2024 14:33:49 GMT
return new DateTime(source, FastDateFormat.getInstance(DatePattern.HTTP_DATETIME_PATTERN, Locale.CHINA));
}
// 例如Thu, 28 Mar 2024 14:33:49 GMT
return new DateTime(source, DatePattern.HTTP_DATETIME_FORMAT);
}
if(StrUtil.contains(source, KEYWORDS_LOCALE_CHINA)){
// 例如星期四, 28 三月 2024 14:33:49 GMT
return new DateTime(source, FastDateFormat.getInstance(DatePattern.JDK_DATETIME_PATTERN, Locale.CHINA));
}
// 例如Thu 28 Mar 2024 14:33:49 GMT
return new DateTime(source, DatePattern.JDK_DATETIME_FORMAT);
}
}

View File

@ -37,7 +37,7 @@ public class RegisterDateParser extends DefaultDateBasic implements DateParser {
// 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,
RFC2822DateParser.INSTANCE,
// ISO8601标准时间
// yyyy-MM-dd'T'HH:mm:ss'Z'
// yyyy-MM-dd'T'HH:mm:ss+0800

View File

@ -45,6 +45,10 @@ public class TimeParser extends DefaultDateBasic implements PredicateDateParser
@Override
public DateTime parse(String source) {
// issue#I9C2D4 处理时分秒
//15时45分59秒 修正为 15:45:59
source = StrUtil.replaceChars(source, "时分秒", ":");
source = StrUtil.format("{} {}", DateUtil.formatToday(), source);
if (1 == StrUtil.count(source, ':')) {
// 时间格式为 HH:mm

View File

@ -148,7 +148,7 @@ public interface RegexPool {
/**
* 时间正则
*/
String TIME = "\\d{1,2}:\\d{1,2}(:\\d{1,2})?";
String TIME = "\\d{1,2}[:时]\\d{1,2}([:分]\\d{1,2})?秒?";
/**
* 中国车牌号码兼容新能源车牌
*/

View File

@ -0,0 +1,36 @@
package org.dromara.hutool.core.date;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.Objects;
public class IssueI9C2D4Test {
@Test
public void parseHttpTest() {
final String dateStr = "Thu, 28 Mar 2024 14:33:49 GMT";
final DateTime parse = DateUtil.parse(dateStr);
Assertions.assertEquals("2024-03-28 14:33:49", Objects.requireNonNull(parse).toString());
}
@Test
public void parseHttpTest2() {
final String dateStr = "星期四, 28 三月 2024 14:33:49 GMT";
final DateTime parse = DateUtil.parse(dateStr);
Assertions.assertEquals("2024-03-28 14:33:49", Objects.requireNonNull(parse).toString());
}
@Test
public void parseTimeTest() {
final String dateStr = "15时45分59秒";
final DateTime parse = DateUtil.parse(dateStr);
Assertions.assertEquals("15:45:59", Objects.requireNonNull(parse).toString().split(" ")[1]);
}
@Test
public void parseTimeTest2() {
final String dateStr = "15:45:59";
final DateTime parse = DateUtil.parse(dateStr);
Assertions.assertEquals("15:45:59", Objects.requireNonNull(parse).toString().split(" ")[1]);
}
}