mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
fix code
This commit is contained in:
parent
1ee014bdae
commit
481281f700
@ -2,9 +2,10 @@ 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.parser.DateParser;
|
||||
import cn.hutool.core.date.format.parser.FastDateParser;
|
||||
import cn.hutool.core.date.format.GlobalCustomFormat;
|
||||
import cn.hutool.core.date.format.parser.PositionDateParser;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.hutool.core.text.StrUtil;
|
||||
|
||||
@ -758,7 +759,7 @@ public class CalendarUtil {
|
||||
* @return 解析后的 {@link Calendar},解析失败返回{@code null}
|
||||
* @since 5.7.14
|
||||
*/
|
||||
public static Calendar parse(final CharSequence str, final boolean lenient, final DateParser parser) {
|
||||
public static Calendar parse(final CharSequence str, final boolean lenient, final PositionDateParser parser) {
|
||||
final Calendar calendar = Calendar.getInstance(parser.getTimeZone(), parser.getLocale());
|
||||
calendar.clear();
|
||||
calendar.setLenient(lenient);
|
||||
|
@ -1,12 +1,13 @@
|
||||
package cn.hutool.core.date;
|
||||
|
||||
import cn.hutool.core.date.format.DateParser;
|
||||
import cn.hutool.core.date.format.DatePrinter;
|
||||
import cn.hutool.core.date.format.FastDateFormat;
|
||||
import cn.hutool.core.date.format.GlobalCustomFormat;
|
||||
import cn.hutool.core.date.format.parser.DateParser;
|
||||
import cn.hutool.core.date.format.parser.PositionDateParser;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.hutool.core.text.StrUtil;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.hutool.core.util.SystemUtil;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
@ -310,7 +311,7 @@ public class DateTime extends Date {
|
||||
* @param dateParser 格式化器 {@link DateParser},可以使用 {@link FastDateFormat}
|
||||
* @see DatePattern
|
||||
*/
|
||||
public DateTime(final CharSequence dateStr, final DateParser dateParser) {
|
||||
public DateTime(final CharSequence dateStr, final PositionDateParser dateParser) {
|
||||
this(dateStr, dateParser, SystemUtil.getBoolean(SystemUtil.HUTOOL_DATE_LENIENT, true));
|
||||
}
|
||||
|
||||
@ -322,7 +323,7 @@ public class DateTime extends Date {
|
||||
* @param lenient 是否宽容模式
|
||||
* @see DatePattern
|
||||
*/
|
||||
public DateTime(final CharSequence dateStr, final DateParser dateParser, final boolean lenient) {
|
||||
public DateTime(final CharSequence dateStr, final PositionDateParser dateParser, final boolean lenient) {
|
||||
this(parse(dateStr, dateParser, lenient));
|
||||
}
|
||||
|
||||
@ -1087,7 +1088,7 @@ public class DateTime extends Date {
|
||||
* @param lenient 是否宽容模式
|
||||
* @return {@link Calendar}
|
||||
*/
|
||||
private static Calendar parse(final CharSequence dateStr, final DateParser parser, final boolean lenient) {
|
||||
private static Calendar parse(final CharSequence dateStr, final PositionDateParser parser, final boolean lenient) {
|
||||
Assert.notNull(parser, "Parser or DateFromat must be not null !");
|
||||
Assert.notBlank(dateStr, "Date String must be not blank !");
|
||||
|
||||
|
@ -2,16 +2,20 @@ package cn.hutool.core.date;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.comparator.CompareUtil;
|
||||
import cn.hutool.core.date.format.DateParser;
|
||||
import cn.hutool.core.date.format.DatePrinter;
|
||||
import cn.hutool.core.date.format.FastDateFormat;
|
||||
import cn.hutool.core.date.format.GlobalCustomFormat;
|
||||
import cn.hutool.core.date.format.parser.CSTDateParser;
|
||||
import cn.hutool.core.date.format.parser.DateParser;
|
||||
import cn.hutool.core.date.format.parser.NormalDateParser;
|
||||
import cn.hutool.core.date.format.parser.PureDateParser;
|
||||
import cn.hutool.core.date.format.parser.TimeParser;
|
||||
import cn.hutool.core.date.format.parser.UTCDateParser;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.math.NumberUtil;
|
||||
import cn.hutool.core.regex.PatternPool;
|
||||
import cn.hutool.core.regex.ReUtil;
|
||||
import cn.hutool.core.text.StrUtil;
|
||||
import cn.hutool.core.util.CharUtil;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
@ -656,28 +660,6 @@ public class DateUtil extends CalendarUtil {
|
||||
|
||||
// ------------------------------------ Parse start ----------------------------------------------
|
||||
|
||||
/**
|
||||
* 构建LocalDateTime对象<br>
|
||||
* 格式:yyyy-MM-dd HH:mm:ss
|
||||
*
|
||||
* @param dateStr 时间字符串(带格式)
|
||||
* @return LocalDateTime对象
|
||||
*/
|
||||
public static LocalDateTime parseLocalDateTime(final CharSequence dateStr) {
|
||||
return parseLocalDateTime(dateStr, DatePattern.NORM_DATETIME_PATTERN);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建LocalDateTime对象
|
||||
*
|
||||
* @param dateStr 时间字符串(带格式)
|
||||
* @param format 使用{@link DatePattern}定义的格式
|
||||
* @return LocalDateTime对象
|
||||
*/
|
||||
public static LocalDateTime parseLocalDateTime(final CharSequence dateStr, final String format) {
|
||||
return TimeUtil.parse(dateStr, format);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建DateTime对象
|
||||
*
|
||||
@ -765,154 +747,7 @@ public class DateUtil extends CalendarUtil {
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public static DateTime parse(final String str, final String... parsePatterns) throws DateException {
|
||||
return new DateTime(CalendarUtil.parseByPatterns(str, parsePatterns));
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析日期时间字符串,格式支持:
|
||||
*
|
||||
* <pre>
|
||||
* yyyy-MM-dd HH:mm:ss
|
||||
* yyyy/MM/dd HH:mm:ss
|
||||
* yyyy.MM.dd HH:mm:ss
|
||||
* yyyy年MM月dd日 HH:mm:ss
|
||||
* </pre>
|
||||
*
|
||||
* @param dateString 标准形式的时间字符串
|
||||
* @return 日期对象
|
||||
*/
|
||||
public static DateTime parseDateTime(CharSequence dateString) {
|
||||
dateString = normalize(dateString);
|
||||
return parse(dateString, DatePattern.NORM_DATETIME_FORMAT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析日期字符串,忽略时分秒,支持的格式包括:
|
||||
* <pre>
|
||||
* yyyy-MM-dd
|
||||
* yyyy/MM/dd
|
||||
* yyyy.MM.dd
|
||||
* yyyy年MM月dd日
|
||||
* </pre>
|
||||
*
|
||||
* @param dateString 标准形式的日期字符串
|
||||
* @return 日期对象
|
||||
*/
|
||||
public static DateTime parseDate(CharSequence dateString) {
|
||||
dateString = normalize(dateString);
|
||||
return parse(dateString, DatePattern.NORM_DATE_FORMAT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析时间,格式HH:mm:ss,日期部分默认为1970-01-01
|
||||
*
|
||||
* @param timeString 标准形式的日期字符串
|
||||
* @return 日期对象
|
||||
*/
|
||||
public static DateTime parseTime(CharSequence timeString) {
|
||||
timeString = normalize(timeString);
|
||||
return parse(timeString, DatePattern.NORM_TIME_FORMAT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析时间,格式HH:mm 或 HH:mm:ss,日期默认为今天
|
||||
*
|
||||
* @param timeString 标准形式的日期字符串
|
||||
* @return 日期对象
|
||||
* @since 3.1.1
|
||||
*/
|
||||
public static DateTime parseTimeToday(CharSequence timeString) {
|
||||
timeString = StrUtil.format("{} {}", formatToday(), timeString);
|
||||
if (1 == StrUtil.count(timeString, ':')) {
|
||||
// 时间格式为 HH:mm
|
||||
return parse(timeString, DatePattern.NORM_DATETIME_MINUTE_PATTERN);
|
||||
} else {
|
||||
// 时间格式为 HH:mm:ss
|
||||
return parse(timeString, DatePattern.NORM_DATETIME_FORMAT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析UTC时间,格式:<br>
|
||||
* <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>
|
||||
*
|
||||
* @param utcString UTC时间
|
||||
* @return 日期对象
|
||||
* @since 4.1.14
|
||||
*/
|
||||
public static DateTime parseUTC(String utcString) {
|
||||
if (utcString == null) {
|
||||
return null;
|
||||
}
|
||||
final int length = utcString.length();
|
||||
if (StrUtil.contains(utcString, 'Z')) {
|
||||
if (length == DatePattern.UTC_PATTERN.length() - 4) {
|
||||
// 格式类似:2018-09-13T05:34:31Z,-4表示减去4个单引号的长度
|
||||
return parse(utcString, DatePattern.UTC_FORMAT);
|
||||
}
|
||||
|
||||
final int patternLength = DatePattern.UTC_MS_PATTERN.length();
|
||||
// 格式类似:2018-09-13T05:34:31.999Z,-4表示减去4个单引号的长度
|
||||
// -4 ~ -6范围表示匹配毫秒1~3位的情况
|
||||
if (length <= patternLength - 4 && length >= patternLength - 6) {
|
||||
return parse(utcString, DatePattern.UTC_MS_FORMAT);
|
||||
}
|
||||
} else if (StrUtil.contains(utcString, '+')) {
|
||||
// 去除类似2019-06-01T19:45:43 +08:00加号前的空格
|
||||
utcString = utcString.replace(" +", "+");
|
||||
final String zoneOffset = StrUtil.subAfter(utcString, '+', true);
|
||||
if (StrUtil.isBlank(zoneOffset)) {
|
||||
throw new DateException("Invalid format: [{}]", utcString);
|
||||
}
|
||||
if (false == StrUtil.contains(zoneOffset, ':')) {
|
||||
// +0800转换为+08:00
|
||||
final String pre = StrUtil.subBefore(utcString, '+', true);
|
||||
utcString = pre + "+" + zoneOffset.substring(0, 2) + ":" + "00";
|
||||
}
|
||||
|
||||
if (StrUtil.contains(utcString, CharUtil.DOT)) {
|
||||
// 带毫秒,格式类似:2018-09-13T05:34:31.999+08:00
|
||||
return parse(utcString, DatePattern.UTC_MS_WITH_XXX_OFFSET_FORMAT);
|
||||
} else {
|
||||
// 格式类似:2018-09-13T05:34:31+08:00
|
||||
return parse(utcString, DatePattern.UTC_WITH_XXX_OFFSET_FORMAT);
|
||||
}
|
||||
} else {
|
||||
if (length == DatePattern.UTC_SIMPLE_PATTERN.length() - 2) {
|
||||
// 格式类似:2018-09-13T05:34:31
|
||||
return parse(utcString, DatePattern.UTC_SIMPLE_FORMAT);
|
||||
} else if (StrUtil.contains(utcString, CharUtil.DOT)) {
|
||||
// 可能为: 2021-03-17T06:31:33.99
|
||||
return parse(utcString, DatePattern.UTC_SIMPLE_MS_FORMAT);
|
||||
}
|
||||
}
|
||||
// 没有更多匹配的时间格式
|
||||
throw new DateException("No format fit for date String [{}] !", utcString);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析CST时间,格式:<br>
|
||||
* <ol>
|
||||
* <li>EEE MMM dd HH:mm:ss z yyyy(例如:Wed Aug 01 00:00:00 CST 2012)</li>
|
||||
* </ol>
|
||||
*
|
||||
* @param cstString UTC时间
|
||||
* @return 日期对象
|
||||
* @since 4.6.9
|
||||
*/
|
||||
public static DateTime parseCST(final CharSequence cstString) {
|
||||
if (cstString == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return parse(cstString, DatePattern.JDK_DATETIME_FORMAT);
|
||||
return date(CalendarUtil.parseByPatterns(str, parsePatterns));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -951,64 +786,33 @@ public class DateUtil extends CalendarUtil {
|
||||
String dateStr = dateCharSequence.toString();
|
||||
// 去掉两边空格并去掉中文日期中的“日”和“秒”,以规范长度
|
||||
dateStr = StrUtil.removeAll(dateStr.trim(), '日', '秒');
|
||||
final int length = dateStr.length();
|
||||
|
||||
if (NumberUtil.isNumber(dateStr)) {
|
||||
// 纯数字形式
|
||||
if (length == DatePattern.PURE_DATETIME_PATTERN.length()) {
|
||||
return parse(dateStr, DatePattern.PURE_DATETIME_FORMAT);
|
||||
} else if (length == DatePattern.PURE_DATETIME_MS_PATTERN.length()) {
|
||||
return parse(dateStr, DatePattern.PURE_DATETIME_MS_FORMAT);
|
||||
} else if (length == DatePattern.PURE_DATE_PATTERN.length()) {
|
||||
return parse(dateStr, DatePattern.PURE_DATE_FORMAT);
|
||||
} else if (length == DatePattern.PURE_TIME_PATTERN.length()) {
|
||||
return parse(dateStr, DatePattern.PURE_TIME_FORMAT);
|
||||
}
|
||||
return PureDateParser.INSTANCE.parse(dateStr);
|
||||
} else if (ReUtil.isMatch(PatternPool.TIME, dateStr)) {
|
||||
// HH:mm:ss 或者 HH:mm 时间格式匹配单独解析
|
||||
return parseTimeToday(dateStr);
|
||||
return TimeParser.INSTANCE.parse(dateStr);
|
||||
} else if (StrUtil.containsAnyIgnoreCase(dateStr, wtb)) {
|
||||
// JDK的Date对象toString默认格式,类似于:
|
||||
// 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
|
||||
return parseCST(dateStr);
|
||||
return CSTDateParser.INSTANCE.parse(dateStr);
|
||||
} else if (StrUtil.contains(dateStr, 'T')) {
|
||||
// UTC时间
|
||||
return parseUTC(dateStr);
|
||||
return UTCDateParser.INSTANCE.parse(dateStr);
|
||||
}
|
||||
|
||||
//标准日期格式(包括单个数字的日期时间)
|
||||
dateStr = normalize(dateStr);
|
||||
if (ReUtil.isMatch(DatePattern.REGEX_NORM, dateStr)) {
|
||||
final int colonCount = StrUtil.count(dateStr, CharUtil.COLON);
|
||||
switch (colonCount) {
|
||||
case 0:
|
||||
// yyyy-MM-dd
|
||||
return parse(dateStr, DatePattern.NORM_DATE_FORMAT);
|
||||
case 1:
|
||||
// yyyy-MM-dd HH:mm
|
||||
return parse(dateStr, DatePattern.NORM_DATETIME_MINUTE_FORMAT);
|
||||
case 2:
|
||||
final int indexOfDot = StrUtil.indexOf(dateStr, CharUtil.DOT);
|
||||
if (indexOfDot > 0) {
|
||||
final int length1 = dateStr.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,采取截断操作
|
||||
dateStr = StrUtil.subPre(dateStr, indexOfDot + 4);
|
||||
}
|
||||
return parse(dateStr, DatePattern.NORM_DATETIME_MS_FORMAT);
|
||||
}
|
||||
// yyyy-MM-dd HH:mm:ss
|
||||
return parse(dateStr, DatePattern.NORM_DATETIME_FORMAT);
|
||||
}
|
||||
return NormalDateParser.INSTANCE.parse(dateStr);
|
||||
}
|
||||
|
||||
// 没有更多匹配的时间格式
|
||||
throw new DateException("No format fit for date String [{}] !", dateStr);
|
||||
}
|
||||
|
||||
// ------------------------------------ Parse end ----------------------------------------------
|
||||
|
||||
// ------------------------------------ Offset start ----------------------------------------------
|
||||
|
@ -0,0 +1,34 @@
|
||||
package cn.hutool.core.date.format;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* 默认日期基本信息类,包括:
|
||||
* <ul>
|
||||
* <li>{@link #getPattern()}返回{@code null}</li>
|
||||
* <li>{@link #getTimeZone()} ()}返回{@link TimeZone#getDefault()}</li>
|
||||
* <li>{@link #getLocale()} ()} ()}返回{@link Locale#getDefault()}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author looly
|
||||
*/
|
||||
public class DefaultDateBasic implements DateBasic, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public String getPattern() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeZone getTimeZone() {
|
||||
return TimeZone.getDefault();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locale getLocale() {
|
||||
return Locale.getDefault();
|
||||
}
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
package cn.hutool.core.date.format;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.format.parser.FastDateParser;
|
||||
import cn.hutool.core.date.format.parser.PositionDateParser;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.FieldPosition;
|
||||
@ -29,7 +31,7 @@ import java.util.TimeZone;
|
||||
* Thanks to Apache Commons Lang 3.5
|
||||
* @since 2.16.2
|
||||
*/
|
||||
public class FastDateFormat extends Format implements DateParser, DatePrinter {
|
||||
public class FastDateFormat extends Format implements PositionDateParser, DatePrinter {
|
||||
private static final long serialVersionUID = 8097890768636183236L;
|
||||
|
||||
/** FULL locale dependent date or time style. */
|
||||
|
@ -1,6 +1,7 @@
|
||||
package cn.hutool.core.date.format;
|
||||
|
||||
import cn.hutool.core.date.DateException;
|
||||
import cn.hutool.core.date.format.parser.FastDateParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
@ -20,7 +21,7 @@ import java.util.concurrent.ConcurrentMap;
|
||||
*
|
||||
* @see FastDateParser
|
||||
*/
|
||||
public class FastDatePrinter extends AbstractDateBasic implements DatePrinter {
|
||||
public class FastDatePrinter extends SimpleDateBasic implements DatePrinter {
|
||||
private static final long serialVersionUID = -6305750172255764887L;
|
||||
|
||||
/** 规则列表. */
|
||||
|
@ -4,23 +4,35 @@ import java.io.Serializable;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public abstract class AbstractDateBasic implements DateBasic, Serializable {
|
||||
/**
|
||||
* 抽象日期基本信息类,包括日期格式、时区、本地化等信息
|
||||
*
|
||||
* @author looly
|
||||
*/
|
||||
public class SimpleDateBasic implements DateBasic, Serializable {
|
||||
private static final long serialVersionUID = 6333136319870641818L;
|
||||
|
||||
/** The pattern */
|
||||
/**
|
||||
* The pattern
|
||||
*/
|
||||
protected final String pattern;
|
||||
/** The time zone. */
|
||||
/**
|
||||
* The time zone.
|
||||
*/
|
||||
protected final TimeZone timeZone;
|
||||
/** The locale. */
|
||||
/**
|
||||
* The locale.
|
||||
*/
|
||||
protected final Locale locale;
|
||||
|
||||
/**
|
||||
* 构造,内部使用
|
||||
*
|
||||
* @param pattern 使用{@link java.text.SimpleDateFormat} 相同的日期格式
|
||||
* @param timeZone 非空时区{@link TimeZone}
|
||||
* @param locale 非空{@link Locale} 日期地理位置
|
||||
*/
|
||||
protected AbstractDateBasic(final String pattern, final TimeZone timeZone, final Locale locale) {
|
||||
protected SimpleDateBasic(final String pattern, final TimeZone timeZone, final Locale locale) {
|
||||
this.pattern = pattern;
|
||||
this.timeZone = timeZone;
|
||||
this.locale = locale;
|
||||
@ -48,7 +60,7 @@ public abstract class AbstractDateBasic implements DateBasic, Serializable {
|
||||
if (obj instanceof FastDatePrinter == false) {
|
||||
return false;
|
||||
}
|
||||
final AbstractDateBasic other = (AbstractDateBasic) obj;
|
||||
final SimpleDateBasic other = (SimpleDateBasic) obj;
|
||||
return pattern.equals(other.pattern) && timeZone.equals(other.timeZone) && locale.equals(other.locale);
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
package cn.hutool.core.date.format.parser;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.format.DefaultDateBasic;
|
||||
|
||||
/**
|
||||
* CST日期字符串(JDK的Date对象toString默认格式)解析,支持格式类似于;
|
||||
* <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
|
||||
* </pre>
|
||||
*
|
||||
* @author looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class CSTDateParser extends DefaultDateBasic implements DateParser {
|
||||
|
||||
public static CSTDateParser INSTANCE = new CSTDateParser();
|
||||
|
||||
@Override
|
||||
public DateTime parse(final String source) {
|
||||
return new DateTime(source, DatePattern.JDK_DATETIME_FORMAT);
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package cn.hutool.core.date.format.parser;
|
||||
|
||||
import cn.hutool.core.date.format.DateBasic;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 日期解析接口,用于解析日期字符串为 {@link Date} 对象<br>
|
||||
* Thanks to Apache Commons Lang 3.5
|
||||
*/
|
||||
public interface DateParser extends DateBasic {
|
||||
|
||||
/**
|
||||
* 将日期字符串解析并转换为 {@link Date} 对象<br>
|
||||
* 等价于 {@link java.text.DateFormat#parse(String)}
|
||||
*
|
||||
* @param source 被解析的日期字符串
|
||||
* @return {@link Date}对象
|
||||
* @throws ParseException 转换异常,被转换的字符串格式错误。
|
||||
*/
|
||||
Date parse(String source) throws ParseException;
|
||||
|
||||
/**
|
||||
* 将日期字符串解析并转换为 {@link Date} 对象<br>
|
||||
*
|
||||
* @param source 被解析的日期字符串
|
||||
* @return {@link Date}对象
|
||||
* @throws ParseException if the beginning of the specified string cannot be parsed.
|
||||
* @see java.text.DateFormat#parseObject(String)
|
||||
*/
|
||||
default Object parseObject(final String source) throws ParseException {
|
||||
return parse(source);
|
||||
}
|
||||
}
|
@ -1,4 +1,8 @@
|
||||
package cn.hutool.core.date.format;
|
||||
package cn.hutool.core.date.format.parser;
|
||||
|
||||
import cn.hutool.core.date.format.FastDateFormat;
|
||||
import cn.hutool.core.date.format.FastDatePrinter;
|
||||
import cn.hutool.core.date.format.SimpleDateBasic;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
@ -30,7 +34,7 @@ import java.util.regex.Pattern;
|
||||
* @see FastDatePrinter
|
||||
* @since 2.16.2
|
||||
*/
|
||||
public class FastDateParser extends AbstractDateBasic implements DateParser {
|
||||
public class FastDateParser extends SimpleDateBasic implements PositionDateParser {
|
||||
private static final long serialVersionUID = -3199383897950947498L;
|
||||
|
||||
static final Locale JAPANESE_IMPERIAL = new Locale("ja", "JP", "JP");
|
@ -0,0 +1,54 @@
|
||||
package cn.hutool.core.date.format.parser;
|
||||
|
||||
import cn.hutool.core.date.DateException;
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.format.DefaultDateBasic;
|
||||
import cn.hutool.core.text.StrUtil;
|
||||
import cn.hutool.core.util.CharUtil;
|
||||
|
||||
/**
|
||||
* 标准日期字符串解析,支持格式;
|
||||
* <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 extends DefaultDateBasic implements DateParser {
|
||||
|
||||
public static NormalDateParser INSTANCE = new NormalDateParser();
|
||||
|
||||
@Override
|
||||
public DateTime parse(String source) {
|
||||
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);
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
package cn.hutool.core.date.format.parser;
|
||||
|
||||
import cn.hutool.core.date.CalendarUtil;
|
||||
import cn.hutool.core.date.DateException;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.format.DefaultDateBasic;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* 通过给定的日期格式解析日期时间字符串。<br>
|
||||
* 传入的日期格式会逐个尝试,直到解析成功,返回{@link Calendar}对象,否则抛出{@link DateException}异常。
|
||||
*
|
||||
* @author looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class PatternsDateParser extends DefaultDateBasic implements DateParser {
|
||||
|
||||
/**
|
||||
* 创建 PatternsDateParser
|
||||
*
|
||||
* @param parsePatterns 多个日期格式
|
||||
* @return PatternsDateParser
|
||||
*/
|
||||
public static PatternsDateParser of(final String... parsePatterns) {
|
||||
return new PatternsDateParser(parsePatterns);
|
||||
}
|
||||
|
||||
private String[] parsePatterns;
|
||||
private Locale locale;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param parsePatterns 多个日期格式
|
||||
*/
|
||||
public PatternsDateParser(final String... parsePatterns) {
|
||||
this.parsePatterns = parsePatterns;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置多个日期格式
|
||||
*
|
||||
* @param parsePatterns 日期格式列表
|
||||
* @return this
|
||||
*/
|
||||
public PatternsDateParser setParsePatterns(final String... parsePatterns) {
|
||||
this.parsePatterns = parsePatterns;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置{@link Locale}
|
||||
*
|
||||
* @param locale {@link Locale}
|
||||
* @return this
|
||||
*/
|
||||
public PatternsDateParser setLocale(final Locale locale) {
|
||||
this.locale = locale;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locale getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DateTime parse(final String source) {
|
||||
return new DateTime(CalendarUtil.parseByPatterns(source, this.locale, this.parsePatterns));
|
||||
}
|
||||
}
|
@ -1,26 +1,16 @@
|
||||
package cn.hutool.core.date.format;
|
||||
package cn.hutool.core.date.format.parser;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.ParsePosition;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 日期解析接口,用于解析日期字符串为 {@link Date} 对象<br>
|
||||
* 带有{@link ParsePosition}的日期解析接口,用于解析日期字符串为 {@link Date} 对象<br>
|
||||
* Thanks to Apache Commons Lang 3.5
|
||||
*
|
||||
* @since 2.16.2
|
||||
*/
|
||||
public interface DateParser extends DateBasic{
|
||||
|
||||
/**
|
||||
* 将日期字符串解析并转换为 {@link Date} 对象<br>
|
||||
* 等价于 {@link java.text.DateFormat#parse(String)}
|
||||
*
|
||||
* @param source 日期字符串
|
||||
* @return {@link Date}
|
||||
* @throws ParseException 转换异常,被转换的字符串格式错误。
|
||||
*/
|
||||
Date parse(String source) throws ParseException;
|
||||
public interface PositionDateParser extends DateParser {
|
||||
|
||||
/**
|
||||
* 将日期字符串解析并转换为 {@link Date} 对象<br>
|
||||
@ -46,18 +36,6 @@ public interface DateParser extends DateBasic{
|
||||
*/
|
||||
boolean parse(String source, ParsePosition pos, Calendar calendar);
|
||||
|
||||
/**
|
||||
* 将日期字符串解析并转换为 {@link Date} 对象<br>
|
||||
*
|
||||
* @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)
|
||||
*/
|
||||
default Object parseObject(final String source) throws ParseException{
|
||||
return parse(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 {@link ParsePosition} 给定将日期字符串解析并转换为 {@link Date} 对象<br>
|
||||
*
|
||||
@ -66,7 +44,7 @@ public interface DateParser extends DateBasic{
|
||||
* @return a {@code java.util.Date} object
|
||||
* @see java.text.DateFormat#parseObject(String, ParsePosition)
|
||||
*/
|
||||
default Object parseObject(final String source, final ParsePosition pos){
|
||||
default Object parseObject(final String source, final ParsePosition pos) {
|
||||
return parse(source, pos);
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package cn.hutool.core.date.format.parser;
|
||||
|
||||
import cn.hutool.core.date.DateException;
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.format.DefaultDateBasic;
|
||||
|
||||
/**
|
||||
* 纯数字的日期字符串解析,支持格式包括;
|
||||
* <ul>
|
||||
* <li>yyyyMMddHHmmss</li>
|
||||
* <li>yyyyMMddHHmmssSSS</li>
|
||||
* <li>yyyyMMdd</li>
|
||||
* <li>HHmmss</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class PureDateParser extends DefaultDateBasic implements DateParser {
|
||||
|
||||
public static PureDateParser INSTANCE = new PureDateParser();
|
||||
|
||||
@Override
|
||||
public DateTime parse(final String 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);
|
||||
}
|
||||
|
||||
throw new DateException("No pure format fit for date String [{}] !", source);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package cn.hutool.core.date.format.parser;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.date.format.DefaultDateBasic;
|
||||
import cn.hutool.core.text.StrUtil;
|
||||
|
||||
/**
|
||||
* 时间日期字符串,日期默认为当天,支持格式类似于;
|
||||
* <pre>
|
||||
* HH:mm:ss
|
||||
* HH:mm
|
||||
* </pre>
|
||||
*
|
||||
* @author looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class TimeParser extends DefaultDateBasic implements DateParser {
|
||||
|
||||
public static TimeParser INSTANCE = new TimeParser();
|
||||
|
||||
@Override
|
||||
public DateTime parse(String source) {
|
||||
source = StrUtil.format("{} {}", DateUtil.formatToday(), source);
|
||||
if (1 == StrUtil.count(source, ':')) {
|
||||
// 时间格式为 HH:mm
|
||||
return new DateTime(source, DatePattern.NORM_DATETIME_MINUTE_PATTERN);
|
||||
} else {
|
||||
// 时间格式为 HH:mm:ss
|
||||
return new DateTime(source, DatePattern.NORM_DATETIME_FORMAT);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
package cn.hutool.core.date.format.parser;
|
||||
|
||||
import cn.hutool.core.date.DateException;
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.format.DefaultDateBasic;
|
||||
import cn.hutool.core.text.StrUtil;
|
||||
import cn.hutool.core.util.CharUtil;
|
||||
|
||||
/**
|
||||
* UTC日期字符串(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 UTCDateParser extends DefaultDateBasic implements DateParser {
|
||||
|
||||
public static UTCDateParser INSTANCE = new UTCDateParser();
|
||||
|
||||
@Override
|
||||
public DateTime parse(String source) {
|
||||
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个单引号的长度
|
||||
// -4 ~ -6范围表示匹配毫秒1~3位的情况
|
||||
if (length <= patternLength - 4 && length >= patternLength - 6) {
|
||||
return new DateTime(source, DatePattern.UTC_MS_FORMAT);
|
||||
}
|
||||
} else if (StrUtil.contains(source, '+')) {
|
||||
// 去除类似2019-06-01T19:45:43 +08:00加号前的空格
|
||||
source = source.replace(" +", "+");
|
||||
final String zoneOffset = StrUtil.subAfter(source, '+', true);
|
||||
if (StrUtil.isBlank(zoneOffset)) {
|
||||
throw new DateException("Invalid format: [{}]", source);
|
||||
}
|
||||
if (false == 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
|
||||
return new DateTime(source, DatePattern.UTC_MS_WITH_XXX_OFFSET_FORMAT);
|
||||
} else {
|
||||
// 格式类似:2018-09-13T05:34:31+08:00
|
||||
return new DateTime(source, DatePattern.UTC_WITH_XXX_OFFSET_FORMAT);
|
||||
}
|
||||
} else {
|
||||
if (length == DatePattern.UTC_SIMPLE_PATTERN.length() - 2) {
|
||||
// 格式类似:2018-09-13T05:34:31
|
||||
return new DateTime(source, DatePattern.UTC_SIMPLE_FORMAT);
|
||||
} else if (StrUtil.contains(source, CharUtil.DOT)) {
|
||||
// 可能为: 2021-03-17T06:31:33.99
|
||||
return new DateTime(source, DatePattern.UTC_SIMPLE_MS_FORMAT);
|
||||
}
|
||||
}
|
||||
// 没有更多匹配的时间格式
|
||||
throw new DateException("No UTC format fit for date String [{}] !", source);
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
/**
|
||||
* 提供日期解析相关封装
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
package cn.hutool.core.date.format.parser;
|
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* 字符串切分封装和工具类
|
||||
*
|
||||
* @author looly
|
||||
*/
|
||||
package cn.hutool.core.text.split;
|
Loading…
x
Reference in New Issue
Block a user