From cb7912717e3624da4b5a04d8890ad343a5f146c7 Mon Sep 17 00:00:00 2001 From: Looly Date: Wed, 16 Oct 2019 18:48:25 +0800 Subject: [PATCH] add TemporalAccessorConverter --- CHANGELOG.md | 1 + .../core/convert/ConverterRegistry.java | 77 +++++---- .../core/convert/impl/Jdk8DateConverter.java | 130 -------------- .../impl/TemporalAccessorConverter.java | 160 ++++++++++++++++++ .../java/cn/hutool/core/date/DateTime.java | 50 +++++- .../java/cn/hutool/core/date/DateUtil.java | 83 ++++++--- .../main/java/cn/hutool/core/lang/Assert.java | 20 ++- .../java/cn/hutool/core/lang/Validator.java | 2 +- .../java/cn/hutool/core/util/NumberUtil.java | 11 +- .../TemporalAccessorConverterTest.java | 57 +++++++ 10 files changed, 374 insertions(+), 217 deletions(-) delete mode 100644 hutool-core/src/main/java/cn/hutool/core/convert/impl/Jdk8DateConverter.java create mode 100644 hutool-core/src/main/java/cn/hutool/core/convert/impl/TemporalAccessorConverter.java create mode 100644 hutool-core/src/test/java/cn/hutool/core/convert/TemporalAccessorConverterTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 486aae4ba..3e2f957ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ * 【all】 部分接口添加FunctionalInterface修饰 * 【crypto】 KeyUtil增加readKeyStore重载 * 【extra】 JschUtil增加私钥传入支持(issue#INKDR@Gitee) +* 【core】 DateUtil、DateTime、Convert全面支持jdk8的time包 ### Bug修复 * 【http】 修复Cookie中host失效导致的问题(issue#583@Github) diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java b/hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java index 49632c3fc..4fd26839b 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java @@ -1,28 +1,5 @@ package cn.hutool.core.convert; -import java.io.Serializable; -import java.lang.ref.SoftReference; -import java.lang.ref.WeakReference; -import java.lang.reflect.Type; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.net.URI; -import java.net.URL; -import java.nio.charset.Charset; -import java.nio.file.Path; -import java.util.Calendar; -import java.util.Collection; -import java.util.Currency; -import java.util.Locale; -import java.util.Map; -import java.util.TimeZone; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicReference; - import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.convert.impl.ArrayConverter; import cn.hutool.core.convert.impl.AtomicBooleanConverter; @@ -37,7 +14,6 @@ import cn.hutool.core.convert.impl.CollectionConverter; import cn.hutool.core.convert.impl.CurrencyConverter; import cn.hutool.core.convert.impl.DateConverter; import cn.hutool.core.convert.impl.EnumConverter; -import cn.hutool.core.convert.impl.Jdk8DateConverter; import cn.hutool.core.convert.impl.LocaleConverter; import cn.hutool.core.convert.impl.MapConverter; import cn.hutool.core.convert.impl.NumberConverter; @@ -46,17 +22,47 @@ import cn.hutool.core.convert.impl.PrimitiveConverter; import cn.hutool.core.convert.impl.ReferenceConverter; import cn.hutool.core.convert.impl.StackTraceElementConverter; import cn.hutool.core.convert.impl.StringConverter; +import cn.hutool.core.convert.impl.TemporalAccessorConverter; import cn.hutool.core.convert.impl.TimeZoneConverter; import cn.hutool.core.convert.impl.URIConverter; import cn.hutool.core.convert.impl.URLConverter; import cn.hutool.core.convert.impl.UUIDConverter; import cn.hutool.core.date.DateTime; import cn.hutool.core.lang.TypeReference; -import cn.hutool.core.util.ClassUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.TypeUtil; +import java.io.Serializable; +import java.lang.ref.SoftReference; +import java.lang.ref.WeakReference; +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.net.URI; +import java.net.URL; +import java.nio.charset.Charset; +import java.nio.file.Path; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.OffsetDateTime; +import java.time.OffsetTime; +import java.time.ZonedDateTime; +import java.util.Calendar; +import java.util.Collection; +import java.util.Currency; +import java.util.Locale; +import java.util.Map; +import java.util.TimeZone; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; + /** * 转换器登记中心 *

@@ -371,6 +377,15 @@ public class ConverterRegistry implements Serializable{ defaultConverterMap.put(java.sql.Time.class, new DateConverter(java.sql.Time.class)); defaultConverterMap.put(java.sql.Timestamp.class, new DateConverter(java.sql.Timestamp.class)); + // 日期时间 JDK8+(since 5.0.0) + defaultConverterMap.put(Instant.class, new TemporalAccessorConverter(Instant.class)); + defaultConverterMap.put(LocalDateTime.class, new TemporalAccessorConverter(LocalDateTime.class)); + defaultConverterMap.put(LocalDate.class, new TemporalAccessorConverter(LocalDate.class)); + defaultConverterMap.put(LocalTime.class, new TemporalAccessorConverter(LocalTime.class)); + defaultConverterMap.put(ZonedDateTime.class, new TemporalAccessorConverter(ZonedDateTime.class)); + defaultConverterMap.put(OffsetDateTime.class, new TemporalAccessorConverter(OffsetDateTime.class)); + defaultConverterMap.put(OffsetTime.class, new TemporalAccessorConverter(OffsetTime.class)); + // Reference defaultConverterMap.put(WeakReference.class, new ReferenceConverter(WeakReference.class));// since 3.0.8 defaultConverterMap.put(SoftReference.class, new ReferenceConverter(SoftReference.class));// since 3.0.8 @@ -386,18 +401,6 @@ public class ConverterRegistry implements Serializable{ defaultConverterMap.put(UUID.class, new UUIDConverter());// since 4.0.10 defaultConverterMap.put(StackTraceElement.class, new StackTraceElementConverter());// since 4.5.2 - // JDK8+ - try { - Class clazz; - for (String className : Jdk8DateConverter.supportClassNames) { - clazz = ClassUtil.loadClass(className); - defaultConverterMap.put(clazz, new Jdk8DateConverter(clazz));// since 4.5.1 - } - } catch (Exception e) { - // ignore - // 在使用jdk8以下版本时,其转换器自动跳过失效 - } - return this; } // ----------------------------------------------------------- Private method end diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/impl/Jdk8DateConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/impl/Jdk8DateConverter.java deleted file mode 100644 index e3eede993..000000000 --- a/hutool-core/src/main/java/cn/hutool/core/convert/impl/Jdk8DateConverter.java +++ /dev/null @@ -1,130 +0,0 @@ -package cn.hutool.core.convert.impl; - -import cn.hutool.core.convert.AbstractConverter; -import cn.hutool.core.util.ReflectUtil; - -import java.lang.reflect.Method; -import java.time.Instant; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; - -/** - * JDK8中新加入的java.time包对象解析转换器
- * 通过反射调用“parse方法”,支持的对象包括: - * - *

- * java.time.LocalDateTime
- * java.time.LocalDate
- * java.time.LocalTime
- * java.time.ZonedDateTime
- * java.time.OffsetDateTime
- * java.time.OffsetTime
- * java.time.Period
- * java.time.Instant
- * 
- * - * @author looly - * - */ -public class Jdk8DateConverter extends AbstractConverter { - private static final long serialVersionUID = 1L; - - /** 支持的JDK中的类名 */ - public static String[] supportClassNames = new String[] { // - "java.time.LocalDateTime", // - "java.time.LocalDate", // - "java.time.LocalTime", // - "java.time.ZonedDateTime", // - "java.time.OffsetDateTime", // - "java.time.OffsetTime", // - "java.time.Period", // - "java.time.Instant"// - }; - - private Class targetType; - /** 日期格式化 */ - private String format; - - /** - * 构造 - * - * @param targetType 目标类型 - */ - public Jdk8DateConverter(Class targetType) { - this.targetType = targetType; - } - - /** - * 构造 - * - * @param targetType 目标类型 - * @param format 日期格式 - */ - public Jdk8DateConverter(Class targetType, String format) { - this.targetType = targetType; - this.format = format; - } - - /** - * 获取日期格式 - * - * @return 设置日期格式 - */ - public String getFormat() { - return format; - } - - /** - * 设置日期格式 - * - * @param format 日期格式 - */ - public void setFormat(String format) { - this.format = format; - } - - @Override - protected Object convertInternal(Object value) { - if (value instanceof Long) { - return parseFromLong((Long) value); - } else { - return parseFromCharSequence(convertToStr(value)); - } - } - - /** - * 通过反射从字符串转java.time中的对象 - * - * @param value 字符串值 - * @return 日期对象 - */ - private Object parseFromCharSequence(CharSequence value) { - Method method; - if (null != this.format) { - final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(this.format); - method = ReflectUtil.getMethod(this.targetType, "parse", CharSequence.class, DateTimeFormatter.class); - if(Instant.class.isAssignableFrom(this.targetType)){ - return formatter.parse(value, Instant::from); - } - return ReflectUtil.invokeStatic(method, value, formatter); - } else { - method = ReflectUtil.getMethod(this.targetType, "parse", CharSequence.class); - return ReflectUtil.invokeStatic(method, value); - } - } - - /** - * 通过反射将Long型时间戳转换为java.time中的对象 - * - * @param time 时间戳 - * @return java.time中的对象 - */ - private Object parseFromLong(Long time) { - String targetName = this.targetType.getName(); - if ("java.time.Instant".equals(targetName)) { - return Instant.ofEpochMilli(time); - } - return null; - } -} diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/impl/TemporalAccessorConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/impl/TemporalAccessorConverter.java new file mode 100644 index 000000000..4bbd13a56 --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/convert/impl/TemporalAccessorConverter.java @@ -0,0 +1,160 @@ +package cn.hutool.core.convert.impl; + +import cn.hutool.core.convert.AbstractConverter; +import cn.hutool.core.date.DateUtil; + +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.OffsetDateTime; +import java.time.OffsetTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.temporal.TemporalAccessor; +import java.util.Calendar; +import java.util.Date; + +/** + * JDK8中新加入的java.time包对象解析转换器
+ * 支持的对象包括: + * + *
+ * java.time.Instant
+ * java.time.LocalDateTime
+ * java.time.LocalDate
+ * java.time.LocalTime
+ * java.time.ZonedDateTime
+ * java.time.OffsetDateTime
+ * java.time.OffsetTime
+ * 
+ * + * @author looly + * @since 5.0.0 + */ +public class TemporalAccessorConverter extends AbstractConverter { + private static final long serialVersionUID = 1L; + + private Class targetType; + /** + * 日期格式化 + */ + private String format; + + /** + * 构造 + * + * @param targetType 目标类型 + */ + public TemporalAccessorConverter(Class targetType) { + this.targetType = targetType; + } + + /** + * 构造 + * + * @param targetType 目标类型 + * @param format 日期格式 + */ + public TemporalAccessorConverter(Class targetType, String format) { + this.targetType = targetType; + this.format = format; + } + + /** + * 获取日期格式 + * + * @return 设置日期格式 + */ + public String getFormat() { + return format; + } + + /** + * 设置日期格式 + * + * @param format 日期格式 + */ + public void setFormat(String format) { + this.format = format; + } + + @Override + protected TemporalAccessor convertInternal(Object value) { + if (value instanceof Long) { + return parseFromLong((Long) value); + } else if (value instanceof TemporalAccessor) { + return parseFromTemporalAccessor((TemporalAccessor) value); + } else if (value instanceof Date) { + return parseFromTemporalAccessor(((Date) value).toInstant()); + }else if (value instanceof Calendar) { + return parseFromTemporalAccessor(((Calendar) value).toInstant()); + } else { + return parseFromCharSequence(convertToStr(value)); + } + } + + /** + * 通过反射从字符串转java.time中的对象 + * + * @param value 字符串值 + * @return 日期对象 + */ + private TemporalAccessor parseFromCharSequence(CharSequence value) { + final Instant instant; + if (null != this.format) { + final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(this.format); + instant = formatter.parse(value, Instant::from); + } else { + instant = DateUtil.parse(value).toInstant(); + } + return parseFromTemporalAccessor(instant); + } + + /** + * 将Long型时间戳转换为java.time中的对象 + * + * @param time 时间戳 + * @return java.time中的对象 + */ + private TemporalAccessor parseFromLong(Long time) { + return parseFromTemporalAccessor(Instant.ofEpochMilli(time)); + } + + /** + * 将TemporalAccessor型时间戳转换为java.time中的对象 + * + * @param temporalAccessor TemporalAccessor对象 + * @return java.time中的对象 + */ + private TemporalAccessor parseFromTemporalAccessor(TemporalAccessor temporalAccessor) { + return parseFromIntant(Instant.from(temporalAccessor)); + } + + /** + * 将TemporalAccessor型时间戳转换为java.time中的对象 + * + * @param instant TemporalAccessor对象 + * @return java.time中的对象 + */ + private TemporalAccessor parseFromIntant(Instant instant) { + if(Instant.class.equals(this.targetType)){ + return instant; + }else if (LocalDateTime.class.equals(this.targetType)) { + return LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); + } else if (LocalDate.class.equals(this.targetType)) { + return instant.atZone(ZoneId.systemDefault()).toLocalDate(); + } else if (LocalTime.class.equals(this.targetType)) { + return instant.atZone(ZoneId.systemDefault()).toLocalTime(); + } else if (ZonedDateTime.class.equals(this.targetType)) { + return instant.atZone(ZoneId.systemDefault()); + } else if (OffsetDateTime.class.equals(this.targetType)) { + return OffsetDateTime.ofInstant(instant, ZoneId.systemDefault()); + } else if (OffsetTime.class.equals(this.targetType)) { + return OffsetTime.ofInstant(instant, ZoneId.systemDefault()); + } + return null; + } +} diff --git a/hutool-core/src/main/java/cn/hutool/core/date/DateTime.java b/hutool-core/src/main/java/cn/hutool/core/date/DateTime.java index a8f2fa638..a5fb96be0 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/DateTime.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/DateTime.java @@ -3,6 +3,9 @@ package cn.hutool.core.date; import java.sql.Timestamp; import java.text.DateFormat; import java.text.SimpleDateFormat; +import java.time.Instant; +import java.time.format.DateTimeFormatter; +import java.time.temporal.TemporalAccessor; import java.util.Calendar; import java.util.Date; import java.util.Locale; @@ -143,6 +146,26 @@ public class DateTime extends Date { this.setFirstDayOfWeek(Week.of(calendar.getFirstDayOfWeek())); } + /** + * 给定日期Instant的构造 + * + * @param instant {@link Instant} 对象 + * @since 5.0.0 + */ + public DateTime(Instant instant) { + this(instant.toEpochMilli()); + } + + /** + * 给定日期TemporalAccessor的构造 + * + * @param temporalAccessor {@link TemporalAccessor} 对象 + * @since 5.0.0 + */ + public DateTime(TemporalAccessor temporalAccessor) { + this(Instant.from(temporalAccessor)); + } + /** * 给定日期毫秒数的构造 * @@ -174,7 +197,7 @@ public class DateTime extends Date { * @param format 格式 * @see DatePattern */ - public DateTime(String dateStr, String format) { + public DateTime(CharSequence dateStr, String format) { this(dateStr, new SimpleDateFormat(format)); } @@ -185,10 +208,22 @@ public class DateTime extends Date { * @param dateFormat 格式化器 {@link SimpleDateFormat} * @see DatePattern */ - public DateTime(String dateStr, DateFormat dateFormat) { + public DateTime(CharSequence dateStr, DateFormat dateFormat) { this(parse(dateStr, dateFormat), dateFormat.getTimeZone()); } + /** + * 构建DateTime对象 + * + * @param dateStr Date字符串 + * @param formatter 格式化器,{@link DateTimeFormatter} + * @return DateTime对象 + * @since 5.0.0 + */ + public DateTime(CharSequence dateStr, DateTimeFormatter formatter) { + this(Instant.from(formatter.parse(dateStr))); + } + /** * 构造 * @@ -196,7 +231,7 @@ public class DateTime extends Date { * @param dateParser 格式化器 {@link DateParser},可以使用 {@link FastDateFormat} * @see DatePattern */ - public DateTime(String dateStr, DateParser dateParser) { + public DateTime(CharSequence dateStr, DateParser dateParser) { this(parse(dateStr, dateParser), dateParser.getTimeZone()); } @@ -869,9 +904,10 @@ public class DateTime extends Date { * @param dateFormat {@link SimpleDateFormat} * @return {@link Date} */ - private static Date parse(String dateStr, DateFormat dateFormat) { + private static Date parse(CharSequence dateStr, DateFormat dateFormat) { + Assert.notBlank(dateStr, "Date String must be not blank !"); try { - return dateFormat.parse(dateStr); + return dateFormat.parse(dateStr.toString()); } catch (Exception e) { String pattern; if (dateFormat instanceof SimpleDateFormat) { @@ -890,11 +926,11 @@ public class DateTime extends Date { * @param parser {@link FastDateFormat} * @return {@link Date} */ - private static Date parse(String dateStr, DateParser parser) { + private static Date parse(CharSequence dateStr, DateParser parser) { Assert.notNull(parser, "Parser or DateFromat must be not null !"); Assert.notBlank(dateStr, "Date String must be not blank !"); try { - return parser.parse(dateStr); + return parser.parse(dateStr.toString()); } catch (Exception e) { throw new DateException("Parse [{}] with format [{}] error!", dateStr, parser.getPattern(), e); } diff --git a/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java b/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java index d6b64cfe8..9a356216a 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java @@ -1,15 +1,5 @@ package cn.hutool.core.date; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Locale; -import java.util.concurrent.TimeUnit; - import cn.hutool.core.collection.CollUtil; import cn.hutool.core.comparator.CompareUtil; import cn.hutool.core.convert.Convert; @@ -18,10 +8,22 @@ 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.lang.PatternPool; -import cn.hutool.core.lang.Validator; +import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.ReUtil; import cn.hutool.core.util.StrUtil; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.time.format.DateTimeFormatter; +import java.time.temporal.TemporalAccessor; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Locale; +import java.util.concurrent.TimeUnit; + /** * 时间工具类 * @@ -105,6 +107,18 @@ public class DateUtil { return new DateTime(calendar); } + /** + * {@link TemporalAccessor}类型时间转为{@link DateTime}
+ * 始终根据已有{@link TemporalAccessor} 产生新的{@link DateTime}对象 + * + * @param temporalAccessor {@link TemporalAccessor} + * @return 时间对象 + * @since 5.0.0 + */ + public static DateTime date(TemporalAccessor temporalAccessor) { + return new DateTime(temporalAccessor); + } + /** * 创建Calendar对象,时间为默认时区的当前时间 * @@ -628,7 +642,7 @@ public class DateUtil { * @param dateFormat 格式化器 {@link SimpleDateFormat} * @return DateTime对象 */ - public static DateTime parse(String dateStr, DateFormat dateFormat) { + public static DateTime parse(CharSequence dateStr, DateFormat dateFormat) { return new DateTime(dateStr, dateFormat); } @@ -639,10 +653,22 @@ public class DateUtil { * @param parser 格式化器,{@link FastDateFormat} * @return DateTime对象 */ - public static DateTime parse(String dateStr, DateParser parser) { + public static DateTime parse(CharSequence dateStr, DateParser parser) { return new DateTime(dateStr, parser); } + /** + * 构建DateTime对象 + * + * @param dateStr Date字符串 + * @param formatter 格式化器,{@link DateTimeFormatter} + * @return DateTime对象 + * @since 5.0.0 + */ + public static DateTime parse(CharSequence dateStr, DateTimeFormatter formatter) { + return new DateTime(dateStr, formatter); + } + /** * 将特定格式的日期转换为Date对象 * @@ -650,7 +676,7 @@ public class DateUtil { * @param format 格式,例如yyyy-MM-dd * @return 日期对象 */ - public static DateTime parse(String dateStr, String format) { + public static DateTime parse(CharSequence dateStr, String format) { return new DateTime(dateStr, format); } @@ -663,7 +689,7 @@ public class DateUtil { * @return 日期对象 * @since 4.5.18 */ - public static DateTime parse(String dateStr, String format, Locale locale) { + public static DateTime parse(CharSequence dateStr, String format, Locale locale) { return new DateTime(dateStr, new SimpleDateFormat(format, locale)); } @@ -673,7 +699,7 @@ public class DateUtil { * @param dateString 标准形式的时间字符串 * @return 日期对象 */ - public static DateTime parseDateTime(String dateString) { + public static DateTime parseDateTime(CharSequence dateString) { dateString = normalize(dateString); return parse(dateString, DatePattern.NORM_DATETIME_FORMAT); } @@ -684,7 +710,7 @@ public class DateUtil { * @param dateString 标准形式的日期字符串 * @return 日期对象 */ - public static DateTime parseDate(String dateString) { + public static DateTime parseDate(CharSequence dateString) { dateString = normalize(dateString); return parse(dateString, DatePattern.NORM_DATE_FORMAT); } @@ -695,7 +721,7 @@ public class DateUtil { * @param timeString 标准形式的日期字符串 * @return 日期对象 */ - public static DateTime parseTime(String timeString) { + public static DateTime parseTime(CharSequence timeString) { timeString = normalize(timeString); return parse(timeString, DatePattern.NORM_TIME_FORMAT); } @@ -707,7 +733,7 @@ public class DateUtil { * @return 日期对象 * @since 3.1.1 */ - public static DateTime parseTimeToday(String timeString) { + public static DateTime parseTimeToday(CharSequence timeString) { timeString = StrUtil.format("{} {}", today(), timeString); if (1 == StrUtil.count(timeString, ':')) { // 时间格式为 HH:mm @@ -767,7 +793,7 @@ public class DateUtil { * @return 日期对象 * @since 4.6.9 */ - public static DateTime parseCST(String cstString) { + public static DateTime parseCST(CharSequence cstString) { if (cstString == null) { return null; } @@ -800,18 +826,19 @@ public class DateUtil { *
  • yyyy-MM-dd'T'HH:mm:ss.SSSZ
  • * * - * @param dateStr 日期字符串 + * @param dateCharSequence 日期字符串 * @return 日期 */ - public static DateTime parse(String dateStr) { - if (null == dateStr) { + public static DateTime parse(CharSequence dateCharSequence) { + if (StrUtil.isBlank(dateCharSequence)) { return null; } + String dateStr = dateCharSequence.toString(); // 去掉两边空格并去掉中文日期中的“日”和“秒”,以规范长度 dateStr = StrUtil.removeAll(dateStr.trim(), '日', '秒'); int length = dateStr.length(); - if (Validator.isNumber(dateStr)) { + if (NumberUtil.isNumber(dateStr)) { // 纯数字形式 if (length == DatePattern.PURE_DATETIME_PATTERN.length()) { return parse(dateStr, DatePattern.PURE_DATETIME_FORMAT); @@ -1938,13 +1965,13 @@ public class DateUtil { * * * 当末位是":"时去除之(不存在毫秒时) - * + * * @param dateStr 日期时间字符串 * @return 格式化后的日期字符串 */ - private static String normalize(String dateStr) { + private static String normalize(CharSequence dateStr) { if (StrUtil.isBlank(dateStr)) { - return dateStr; + return StrUtil.str(dateStr); } // 日期时间分开处理 @@ -1952,7 +1979,7 @@ public class DateUtil { final int size = dateAndTime.size(); if (size < 1 || size > 2) { // 非可被标准处理的格式 - return dateStr; + return StrUtil.str(dateStr); } final StringBuilder builder = StrUtil.builder(); diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/Assert.java b/hutool-core/src/main/java/cn/hutool/core/lang/Assert.java index 6a3c5ceec..353acdd0b 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/Assert.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/Assert.java @@ -157,7 +157,8 @@ public class Assert { *
     	 * Assert.notEmpty(name, "Name must not be empty");
     	 * 
    - * + * + * @param 字符串类型 * @param text 被检查字符串 * @param errorMsgTemplate 错误消息模板,变量使用{}表示 * @param params 参数 @@ -165,7 +166,7 @@ public class Assert { * @see StrUtil#isNotEmpty(CharSequence) * @throws IllegalArgumentException 被检查字符串为空 */ - public static String notEmpty(String text, String errorMsgTemplate, Object... params) throws IllegalArgumentException { + public static T notEmpty(T text, String errorMsgTemplate, Object... params) throws IllegalArgumentException { if (StrUtil.isEmpty(text)) { throw new IllegalArgumentException(StrUtil.format(errorMsgTemplate, params)); } @@ -178,13 +179,14 @@ public class Assert { *
     	 * Assert.notEmpty(name);
     	 * 
    - * + * + * @param 字符串类型 * @param text 被检查字符串 * @return 被检查的字符串 * @see StrUtil#isNotEmpty(CharSequence) * @throws IllegalArgumentException 被检查字符串为空 */ - public static String notEmpty(String text) throws IllegalArgumentException { + public static T notEmpty(T text) throws IllegalArgumentException { return notEmpty(text, "[Assertion failed] - this String argument must have length; it must not be null or empty"); } @@ -194,7 +196,8 @@ public class Assert { *
     	 * Assert.notBlank(name, "Name must not be blank");
     	 * 
    - * + * + * @param 字符串类型 * @param text 被检查字符串 * @param errorMsgTemplate 错误消息模板,变量使用{}表示 * @param params 参数 @@ -202,7 +205,7 @@ public class Assert { * @see StrUtil#isNotBlank(CharSequence) * @throws IllegalArgumentException 被检查字符串为空白 */ - public static String notBlank(String text, String errorMsgTemplate, Object... params) throws IllegalArgumentException { + public static T notBlank(T text, String errorMsgTemplate, Object... params) throws IllegalArgumentException { if (StrUtil.isBlank(text)) { throw new IllegalArgumentException(StrUtil.format(errorMsgTemplate, params)); } @@ -215,13 +218,14 @@ public class Assert { *
     	 * Assert.notBlank(name, "Name must not be blank");
     	 * 
    - * + * + * @param 字符串类型 * @param text 被检查字符串 * @return 非空字符串 * @see StrUtil#isNotBlank(CharSequence) * @throws IllegalArgumentException 被检查字符串为空白 */ - public static String notBlank(String text) throws IllegalArgumentException { + public static T notBlank(T text) throws IllegalArgumentException { return notBlank(text, "[Assertion failed] - this String argument must have text; it must not be null, empty, or blank"); } diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/Validator.java b/hutool-core/src/main/java/cn/hutool/core/lang/Validator.java index 2d015a9dd..0dacfd82d 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/Validator.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/Validator.java @@ -562,7 +562,7 @@ public class Validator { * @param value 字符串内容 * @return 是否是数字 */ - public static boolean isNumber(String value) { + public static boolean isNumber(CharSequence value) { return NumberUtil.isNumber(value); } diff --git a/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java index 6293a370d..3499fec3b 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java @@ -1,5 +1,8 @@ package cn.hutool.core.util; +import cn.hutool.core.exceptions.UtilException; +import cn.hutool.core.lang.Assert; + import java.math.BigDecimal; import java.math.BigInteger; import java.math.RoundingMode; @@ -11,10 +14,6 @@ import java.util.HashSet; import java.util.Random; import java.util.Set; -import cn.hutool.core.exceptions.UtilException; -import cn.hutool.core.lang.Assert; -import cn.hutool.core.lang.Console; - /** * 数字工具类
    * 对于精确值计算应该使用 {@link BigDecimal}
    @@ -1057,11 +1056,11 @@ public class NumberUtil { * @param str 字符串值 * @return 是否为数字 */ - public static boolean isNumber(String str) { + public static boolean isNumber(CharSequence str) { if (StrUtil.isBlank(str)) { return false; } - char[] chars = str.toCharArray(); + char[] chars = str.toString().toCharArray(); int sz = chars.length; boolean hasExp = false; boolean hasDecPoint = false; diff --git a/hutool-core/src/test/java/cn/hutool/core/convert/TemporalAccessorConverterTest.java b/hutool-core/src/test/java/cn/hutool/core/convert/TemporalAccessorConverterTest.java new file mode 100644 index 000000000..d8a3f987a --- /dev/null +++ b/hutool-core/src/test/java/cn/hutool/core/convert/TemporalAccessorConverterTest.java @@ -0,0 +1,57 @@ +package cn.hutool.core.convert; + +import org.junit.Assert; +import org.junit.Test; + +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.OffsetDateTime; +import java.time.OffsetTime; +import java.time.ZonedDateTime; + +public class TemporalAccessorConverterTest { + + @Test + public void toInstantTest(){ + Instant instant = Convert.convert(Instant.class, "2019-02-18"); + Assert.assertNotNull(instant); + } + + @Test + public void toLocalDateTimeTest(){ + LocalDateTime localDateTime = Convert.convert(LocalDateTime.class, "2019-02-18"); + Assert.assertEquals("2019-02-18T00:00", localDateTime.toString()); + } + + @Test + public void toLocalDateTest(){ + LocalDate localDate = Convert.convert(LocalDate.class, "2019-02-18"); + Assert.assertEquals("2019-02-18", localDate.toString()); + } + + @Test + public void toLocalTimeTest(){ + LocalTime localTime = Convert.convert(LocalTime.class, "2019-02-18"); + Assert.assertEquals("00:00", localTime.toString()); + } + + @Test + public void toZonedDateTimeTest(){ + ZonedDateTime zonedDateTime = Convert.convert(ZonedDateTime.class, "2019-02-18"); + Assert.assertEquals("2019-02-18T00:00+08:00[GMT+08:00]", zonedDateTime.toString()); + } + + @Test + public void toOffsetDateTimeTest(){ + OffsetDateTime zonedDateTime = Convert.convert(OffsetDateTime.class, "2019-02-18"); + Assert.assertEquals("2019-02-18T00:00+08:00", zonedDateTime.toString()); + } + + @Test + public void toOffsetTimeTest(){ + OffsetTime offsetTime = Convert.convert(OffsetTime.class, "2019-02-18"); + Assert.assertEquals("00:00+08:00", offsetTime.toString()); + } +}