This commit is contained in:
Looly 2024-07-05 00:46:09 +08:00
parent 62c87b28cd
commit 11c370328a
6 changed files with 48 additions and 401 deletions

View File

@ -28,9 +28,11 @@ import java.util.Locale;
import java.util.TimeZone;
/**
* <p>
* FastDateFormat 是一个线程安全的 {@link java.text.SimpleDateFormat} 实现
* </p>
* FastDateFormat 是一个线程安全的 {@link java.text.SimpleDateFormat} 实现
* <ul>
* <li>日期字符串解析</li>
* <li>日期格式化</li>
* </ul>
*
* <p>
* 通过以下静态方法获得此对象: <br>
@ -39,23 +41,31 @@ import java.util.TimeZone;
* {@link #getTimeInstance(int, TimeZone, Locale)}<br>
* {@link #getDateTimeInstance(int, int, TimeZone, Locale)}
* </p>
*
* Thanks to Apache Commons Lang 3.5
*
* @since 2.16.2
*/
public class FastDateFormat extends Format implements PositionDateParser, DatePrinter {
private static final long serialVersionUID = 8097890768636183236L;
/** FULL locale dependent date or time style. */
/**
* FULL locale dependent date or time style.
*/
public static final int FULL = DateFormat.FULL;
/** LONG locale dependent date or time style. */
/**
* LONG locale dependent date or time style.
*/
public static final int LONG = DateFormat.LONG;
/** MEDIUM locale dependent date or time style. */
/**
* MEDIUM locale dependent date or time style.
*/
public static final int MEDIUM = DateFormat.MEDIUM;
/** SHORT locale dependent date or time style. */
/**
* SHORT locale dependent date or time style.
*/
public static final int SHORT = DateFormat.SHORT;
private static final FormatCache<FastDateFormat> CACHE = new FormatCache<FastDateFormat>(){
private static final FormatCache<FastDateFormat> CACHE = new FormatCache<FastDateFormat>() {
@Override
protected FastDateFormat createInstance(final String pattern, final TimeZone timeZone, final Locale locale) {
return new FastDateFormat(pattern, timeZone, locale);
@ -66,6 +76,7 @@ public class FastDateFormat extends Format implements PositionDateParser, DatePr
private final FastDateParser parser;
// -----------------------------------------------------------------------
/**
* 获得 FastDateFormat实例使用默认格式和地区
*
@ -91,7 +102,7 @@ public class FastDateFormat extends Format implements PositionDateParser, DatePr
* 获得 FastDateFormat 实例<br>
* 支持缓存
*
* @param pattern 使用{@link java.text.SimpleDateFormat} 相同的日期格式
* @param pattern 使用{@link java.text.SimpleDateFormat} 相同的日期格式
* @param timeZone 时区{@link TimeZone}
* @return FastDateFormat
* @throws IllegalArgumentException 日期格式问题
@ -105,7 +116,7 @@ public class FastDateFormat extends Format implements PositionDateParser, DatePr
* 支持缓存
*
* @param pattern 使用{@link java.text.SimpleDateFormat} 相同的日期格式
* @param locale {@link Locale} 日期地理位置
* @param locale {@link Locale} 日期地理位置
* @return FastDateFormat
* @throws IllegalArgumentException 日期格式问题
*/
@ -117,9 +128,9 @@ public class FastDateFormat extends Format implements PositionDateParser, DatePr
* 获得 FastDateFormat 实例<br>
* 支持缓存
*
* @param pattern 使用{@link java.text.SimpleDateFormat} 相同的日期格式
* @param pattern 使用{@link java.text.SimpleDateFormat} 相同的日期格式
* @param timeZone 时区{@link TimeZone}
* @param locale {@link Locale} 日期地理位置
* @param locale {@link Locale} 日期地理位置
* @return FastDateFormat
* @throws IllegalArgumentException 日期格式问题
*/
@ -128,6 +139,7 @@ public class FastDateFormat extends Format implements PositionDateParser, DatePr
}
// -----------------------------------------------------------------------
/**
* 获得 FastDateFormat 实例<br>
* 支持缓存
@ -143,7 +155,7 @@ public class FastDateFormat extends Format implements PositionDateParser, DatePr
* 获得 FastDateFormat 实例<br>
* 支持缓存
*
* @param style date style: FULL, LONG, MEDIUM, or SHORT
* @param style date style: FULL, LONG, MEDIUM, or SHORT
* @param locale {@link Locale} 日期地理位置
* @return 本地化 FastDateFormat
*/
@ -155,7 +167,7 @@ public class FastDateFormat extends Format implements PositionDateParser, DatePr
* 获得 FastDateFormat 实例<br>
* 支持缓存
*
* @param style date style: FULL, LONG, MEDIUM, or SHORT
* @param style date style: FULL, LONG, MEDIUM, or SHORT
* @param timeZone 时区{@link TimeZone}
* @return 本地化 FastDateFormat
*/
@ -167,9 +179,9 @@ public class FastDateFormat extends Format implements PositionDateParser, DatePr
* 获得 FastDateFormat 实例<br>
* 支持缓存
*
* @param style date style: FULL, LONG, MEDIUM, or SHORT
* @param style date style: FULL, LONG, MEDIUM, or SHORT
* @param timeZone 时区{@link TimeZone}
* @param locale {@link Locale} 日期地理位置
* @param locale {@link Locale} 日期地理位置
* @return 本地化 FastDateFormat
*/
public static FastDateFormat getDateInstance(final int style, final TimeZone timeZone, final Locale locale) {
@ -177,6 +189,7 @@ public class FastDateFormat extends Format implements PositionDateParser, DatePr
}
// -----------------------------------------------------------------------
/**
* 获得 FastDateFormat 实例<br>
* 支持缓存
@ -192,7 +205,7 @@ public class FastDateFormat extends Format implements PositionDateParser, DatePr
* 获得 FastDateFormat 实例<br>
* 支持缓存
*
* @param style time style: FULL, LONG, MEDIUM, or SHORT
* @param style time style: FULL, LONG, MEDIUM, or SHORT
* @param locale {@link Locale} 日期地理位置
* @return 本地化 FastDateFormat
*/
@ -204,7 +217,7 @@ public class FastDateFormat extends Format implements PositionDateParser, DatePr
* 获得 FastDateFormat 实例<br>
* 支持缓存
*
* @param style time style: FULL, LONG, MEDIUM, or SHORT
* @param style time style: FULL, LONG, MEDIUM, or SHORT
* @param timeZone optional time zone, overrides time zone of formatted time
* @return 本地化 FastDateFormat
*/
@ -216,9 +229,9 @@ public class FastDateFormat extends Format implements PositionDateParser, DatePr
* 获得 FastDateFormat 实例<br>
* 支持缓存
*
* @param style time style: FULL, LONG, MEDIUM, or SHORT
* @param style time style: FULL, LONG, MEDIUM, or SHORT
* @param timeZone optional time zone, overrides time zone of formatted time
* @param locale {@link Locale} 日期地理位置
* @param locale {@link Locale} 日期地理位置
* @return 本地化 FastDateFormat
*/
public static FastDateFormat getTimeInstance(final int style, final TimeZone timeZone, final Locale locale) {
@ -226,6 +239,7 @@ public class FastDateFormat extends Format implements PositionDateParser, DatePr
}
// -----------------------------------------------------------------------
/**
* 获得 FastDateFormat 实例<br>
* 支持缓存
@ -244,7 +258,7 @@ public class FastDateFormat extends Format implements PositionDateParser, DatePr
*
* @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT
* @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT
* @param locale {@link Locale} 日期地理位置
* @param locale {@link Locale} 日期地理位置
* @return 本地化 FastDateFormat
*/
public static FastDateFormat getDateTimeInstance(final int dateStyle, final int timeStyle, final Locale locale) {
@ -257,7 +271,7 @@ public class FastDateFormat extends Format implements PositionDateParser, DatePr
*
* @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT
* @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT
* @param timeZone 时区{@link TimeZone}
* @param timeZone 时区{@link TimeZone}
* @return 本地化 FastDateFormat
*/
public static FastDateFormat getDateTimeInstance(final int dateStyle, final int timeStyle, final TimeZone timeZone) {
@ -270,8 +284,8 @@ public class FastDateFormat extends Format implements PositionDateParser, DatePr
*
* @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT
* @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT
* @param timeZone 时区{@link TimeZone}
* @param locale {@link Locale} 日期地理位置
* @param timeZone 时区{@link TimeZone}
* @param locale {@link Locale} 日期地理位置
* @return 本地化 FastDateFormat
*/
public static FastDateFormat getDateTimeInstance(final int dateStyle, final int timeStyle, final TimeZone timeZone, final Locale locale) {
@ -279,12 +293,13 @@ public class FastDateFormat extends Format implements PositionDateParser, DatePr
}
// ----------------------------------------------------------------------- Constructor start
/**
* 构造
*
* @param pattern 使用{@link java.text.SimpleDateFormat} 相同的日期格式
* @param pattern 使用{@link java.text.SimpleDateFormat} 相同的日期格式
* @param timeZone 非空时区 {@link TimeZone}
* @param locale {@link Locale} 日期地理位置
* @param locale {@link Locale} 日期地理位置
* @throws NullPointerException if pattern, timeZone, or locale is null.
*/
protected FastDateFormat(final String pattern, final TimeZone timeZone, final Locale locale) {
@ -294,9 +309,9 @@ public class FastDateFormat extends Format implements PositionDateParser, DatePr
/**
* 构造
*
* @param pattern 使用{@link java.text.SimpleDateFormat} 相同的日期格式
* @param timeZone 非空时区 {@link TimeZone}
* @param locale {@link Locale} 日期地理位置
* @param pattern 使用{@link java.text.SimpleDateFormat} 相同的日期格式
* @param timeZone 非空时区 {@link TimeZone}
* @param locale {@link Locale} 日期地理位置
* @param centuryStart The start of the 100 year period to use as the "default century" for 2 digit year parsing. If centuryStart is null, defaults to now - 80 years
* @throws NullPointerException if pattern, timeZone, or locale is null.
*/
@ -380,7 +395,7 @@ public class FastDateFormat extends Format implements PositionDateParser, DatePr
}
/**
*估算生成的日期字符串长度<br>
* 估算生成的日期字符串长度<br>
* 实际生成的字符串长度小于或等于此值
*
* @return 日期字符串长度
@ -395,6 +410,7 @@ public class FastDateFormat extends Format implements PositionDateParser, DatePr
/**
* 便捷获取 DateTimeFormatter
* 由于 {@link DatePattern} 很大一部分的格式没有提供 {@link DateTimeFormatter},因此这里提供快捷获取方式
*
* @return DateTimeFormatter
* @author dazer neusoft
* @since 5.6.4

View File

@ -17,7 +17,7 @@ import org.dromara.hutool.core.date.DateTime;
import java.util.regex.Pattern;
/**
* 全局正则日期解析器<br>
* 默认正则日期解析器<br>
* 通过使用预定义或自定义的正则规则解析日期字符串
*
* @author Looly

View File

@ -1,142 +0,0 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* https://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.core.date.format.parser;
import org.dromara.hutool.core.date.DateException;
import org.dromara.hutool.core.date.DatePattern;
import org.dromara.hutool.core.date.DateTime;
import org.dromara.hutool.core.regex.ReUtil;
import org.dromara.hutool.core.text.CharUtil;
import org.dromara.hutool.core.text.StrUtil;
import java.io.Serializable;
/**
* ISO8601日期字符串JDK的Date对象toString默认格式解析支持格式
* <ol>
* <li>yyyy-MM-dd'T'HH:mm:ss'Z'</li>
* <li>yyyy-MM-dd'T'HH:mm:ss.SSS'Z'</li>
* <li>yyyy-MM-dd'T'HH:mm:ssZ</li>
* <li>yyyy-MM-dd'T'HH:mm:ss.SSSZ</li>
* <li>yyyy-MM-dd'T'HH:mm:ss+0800</li>
* <li>yyyy-MM-dd'T'HH:mm:ss+08:00</li>
* </ol>
*
* @author looly
* @since 6.0.0
*/
public class ISO8601DateParser implements PredicateDateParser, Serializable {
private static final long serialVersionUID = 1L;
/**
* 单例对象
*/
public static ISO8601DateParser INSTANCE = new ISO8601DateParser();
@Override
public boolean test(final CharSequence dateStr) {
return StrUtil.contains(dateStr, 'T');
}
@Override
public DateTime parse(CharSequence source) throws DateException{
final int length = source.length();
if (StrUtil.contains(source, 'Z')) {
if (length == DatePattern.UTC_PATTERN.length() - 4) {
// 格式类似2018-09-13T05:34:31Z-4表示减去4个单引号的长度
return new DateTime(source, DatePattern.UTC_FORMAT);
}
final int patternLength = DatePattern.UTC_MS_PATTERN.length();
// 格式类似2018-09-13T05:34:31.999Z-4表示减去4个单引号的长度
// 2018-09-13T05:34:31.1Z - 2018-09-13T05:34:31.000000Z
if (length <= patternLength && length >= patternLength - 6) {
// 毫秒部分1-7位支持
return new DateTime(source, DatePattern.UTC_MS_FORMAT);
}
} else if (StrUtil.contains(source, '+')) {
// 去除类似2019-06-01T19:45:43 +08:00加号前的空格
source = StrUtil.replace(source, " +", "+");
final String zoneOffset = StrUtil.subAfter(source, '+', true);
if (StrUtil.isBlank(zoneOffset)) {
throw new DateException("Invalid format: [{}]", source);
}
if (!StrUtil.contains(zoneOffset, ':')) {
// +0800转换为+08:00
final String pre = StrUtil.subBefore(source, '+', true);
source = pre + "+" + zoneOffset.substring(0, 2) + ":" + "00";
}
if (StrUtil.contains(source, CharUtil.DOT)) {
// 带毫秒格式类似2018-09-13T05:34:31.999+08:00
source = normalizeMillSeconds(source, ".", "+");
return new DateTime(source, DatePattern.ISO8601_MS_WITH_XXX_OFFSET_FORMAT);
} else {
// 格式类似2018-09-13T05:34:31+08:00
return new DateTime(source, DatePattern.ISO8601_WITH_XXX_OFFSET_FORMAT);
}
} else if(ReUtil.contains("-\\d{2}:?00", source)){
// Issue#2612类似 2022-09-14T23:59:00-08:00 或者 2022-09-14T23:59:00-0800
// 去除类似2019-06-01T19:45:43 -08:00加号前的空格
source = StrUtil.replace(source, " -", "-");
if(':' != source.charAt(source.length() - 3)){
source = StrUtil.sub(source, 0, source.length() - 2) + ":00";
}
if (StrUtil.contains(source, CharUtil.DOT)) {
// 带毫秒格式类似2018-09-13T05:34:31.999-08:00
source = normalizeMillSeconds(source, ".", "-");
return new DateTime(source, DatePattern.ISO8601_MS_WITH_XXX_OFFSET_FORMAT);
} else {
// 格式类似2018-09-13T05:34:31-08:00
return new DateTime(source, DatePattern.ISO8601_WITH_XXX_OFFSET_FORMAT);
}
} else {
if (length == DatePattern.ISO8601_PATTERN.length() - 2) {
// 格式类似2018-09-13T05:34:31
return new DateTime(source, DatePattern.ISO8601_FORMAT);
} else if (length == DatePattern.ISO8601_PATTERN.length() - 5) {
// 格式类似2018-09-13T05:34
return new DateTime(source + ":00", DatePattern.ISO8601_FORMAT);
} else if (StrUtil.contains(source, CharUtil.DOT)) {
// 可能为 2021-03-17T06:31:33.99
source = normalizeMillSeconds(source, ".", null);
return new DateTime(source, DatePattern.ISO8601_MS_FORMAT);
}
}
// 没有更多匹配的时间格式
throw new DateException("No UTC format fit for date String [{}] !", source);
}
/**
* 如果日期中的毫秒部分超出3位会导致秒数增加因此只保留前三位<br>
* issue#2887
*
* @param dateStr 日期字符串
* @param before 毫秒部分的前一个字符
* @param after 毫秒部分的后一个字符
* @return 规范之后的毫秒部分
*/
@SuppressWarnings("SameParameterValue")
private static String normalizeMillSeconds(final CharSequence dateStr, final CharSequence before, final CharSequence after) {
if (StrUtil.isBlank(after)) {
final String millOrNaco = StrUtil.subPre(StrUtil.subAfter(dateStr, before, true), 3);
return StrUtil.subBefore(dateStr, before, true) + before + millOrNaco;
}
final String millOrNaco = StrUtil.subPre(StrUtil.subBetween(dateStr, before, after), 3);
return StrUtil.subBefore(dateStr, before, true)
+ before
+ millOrNaco + after + StrUtil.subAfter(dateStr, after, true);
}
}

View File

@ -1,80 +0,0 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* https://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.core.date.format.parser;
import org.dromara.hutool.core.date.DateException;
import org.dromara.hutool.core.date.DatePattern;
import org.dromara.hutool.core.date.DateTime;
import org.dromara.hutool.core.regex.ReUtil;
import org.dromara.hutool.core.text.CharUtil;
import org.dromara.hutool.core.text.StrUtil;
import java.io.Serializable;
import java.util.regex.Pattern;
/**
* 标准日期字符串解析支持格式
* <pre>
* yyyy-MM-dd HH:mm:ss.SSSSSS
* yyyy-MM-dd HH:mm:ss.SSS
* yyyy-MM-dd HH:mm:ss
* yyyy-MM-dd HH:mm
* yyyy-MM-dd
* </pre>
*
* @author looly
* @since 6.0.0
*/
public class NormalDateParser implements PredicateDateParser, Serializable {
private static final long serialVersionUID = 1L;
private static final Pattern patternNorm = Pattern.compile("\\d{4}-\\d{1,2}-\\d{1,2}(\\s\\d{1,2}:\\d{1,2}(:\\d{1,2})?(.\\d{1,6})?)?");
/**
* 单例
*/
public static NormalDateParser INSTANCE = new NormalDateParser();
@Override
public boolean test(final CharSequence dateStr) {
return ReUtil.isMatch(patternNorm, dateStr);
}
@Override
public DateTime parse(CharSequence source) throws DateException{
final int colonCount = StrUtil.count(source, CharUtil.COLON);
switch (colonCount) {
case 0:
// yyyy-MM-dd
return new DateTime(source, DatePattern.NORM_DATE_FORMAT);
case 1:
// yyyy-MM-dd HH:mm
return new DateTime(source, DatePattern.NORM_DATETIME_MINUTE_FORMAT);
case 2:
final int indexOfDot = StrUtil.indexOf(source, CharUtil.DOT);
if (indexOfDot > 0) {
final int length1 = source.length();
// yyyy-MM-dd HH:mm:ss.SSS 或者 yyyy-MM-dd HH:mm:ss.SSSSSS
if (length1 - indexOfDot > 4) {
// 类似yyyy-MM-dd HH:mm:ss.SSSSSS采取截断操作
source = StrUtil.subPre(source, indexOfDot + 4);
}
return new DateTime(source, DatePattern.NORM_DATETIME_MS_FORMAT);
}
// yyyy-MM-dd HH:mm:ss
return new DateTime(source, DatePattern.NORM_DATETIME_FORMAT);
}
throw new DateException("No format fit for date String [{}] !", source);
}
}

View File

@ -1,69 +0,0 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* https://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.core.date.format.parser;
import org.dromara.hutool.core.date.DateException;
import org.dromara.hutool.core.date.DatePattern;
import org.dromara.hutool.core.date.DateTime;
import org.dromara.hutool.core.math.NumberUtil;
import org.dromara.hutool.core.text.StrUtil;
import java.io.Serializable;
/**
* 纯数字的日期字符串解析支持格式包括
* <ul>
* <li>yyyyMMddHHmmss</li>
* <li>yyyyMMddHHmmssSSS</li>
* <li>yyyyMMdd</li>
* <li>HHmmss</li>
* <li>毫秒时间戳</li>
* </ul>
*
* @author looly
* @since 6.0.0
*/
public class PureDateParser implements PredicateDateParser, Serializable {
private static final long serialVersionUID = 1L;
/**
* 单例
*/
public static PureDateParser INSTANCE = new PureDateParser();
@Override
public boolean test(final CharSequence dateStr) {
return NumberUtil.isNumber(dateStr);
}
@Override
public DateTime parse(final CharSequence source) throws DateException {
final int length = source.length();
// 纯数字形式
if (length == DatePattern.PURE_DATETIME_PATTERN.length()) {
return new DateTime(source, DatePattern.PURE_DATETIME_FORMAT);
} else if (length == DatePattern.PURE_DATETIME_MS_PATTERN.length()) {
return new DateTime(source, DatePattern.PURE_DATETIME_MS_FORMAT);
} else if (length == DatePattern.PURE_DATE_PATTERN.length()) {
return new DateTime(source, DatePattern.PURE_DATE_FORMAT);
} else if (length == DatePattern.PURE_TIME_PATTERN.length()) {
return new DateTime(source, DatePattern.PURE_TIME_FORMAT);
} else if(length >= 11 && length <= 13){
// 时间戳
return new DateTime(NumberUtil.parseLong(StrUtil.str(source)));
}
throw new DateException("No pure format fit for date String [{}] !", source);
}
}

View File

@ -1,78 +0,0 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* https://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
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.FastDateFormat;
import org.dromara.hutool.core.text.StrUtil;
import java.io.Serializable;
import java.util.Locale;
/**
* 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 RFC2822DateParser implements PredicateDateParser, Serializable {
private static final long serialVersionUID = 1L;
private static final String KEYWORDS_LOCALE_CHINA = "星期";
/**
* java.util.Date EEE MMM zzz 缩写数组
*/
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"// 时间标准
};
/**
* 单例对象
*/
public static RFC2822DateParser INSTANCE = new RFC2822DateParser();
@Override
public boolean test(final CharSequence dateStr) {
return StrUtil.containsAnyIgnoreCase(dateStr, wtb);
}
@Override
public DateTime parse(final CharSequence 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);
}
}