add TemporalAccessorConverter

This commit is contained in:
Looly 2019-10-16 18:48:25 +08:00
parent 4702174334
commit cb7912717e
10 changed files with 374 additions and 217 deletions

View File

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

View File

@ -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;
/**
* 转换器登记中心
* <p>
@ -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

View File

@ -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包对象解析转换器<br>
* 通过反射调用parse方法支持的对象包括
*
* <pre>
* java.time.LocalDateTime
* java.time.LocalDate
* java.time.LocalTime
* java.time.ZonedDateTime
* java.time.OffsetDateTime
* java.time.OffsetTime
* java.time.Period
* java.time.Instant
* </pre>
*
* @author looly
*
*/
public class Jdk8DateConverter extends AbstractConverter<Object> {
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;
}
}

View File

@ -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包对象解析转换器<br>
* 支持的对象包括
*
* <pre>
* java.time.Instant
* java.time.LocalDateTime
* java.time.LocalDate
* java.time.LocalTime
* java.time.ZonedDateTime
* java.time.OffsetDateTime
* java.time.OffsetTime
* </pre>
*
* @author looly
* @since 5.0.0
*/
public class TemporalAccessorConverter extends AbstractConverter<TemporalAccessor> {
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;
}
}

View File

@ -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);
}

View File

@ -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}<br>
* 始终根据已有{@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 {
* <li>yyyy-MM-dd'T'HH:mm:ss.SSSZ</li>
* </ol>
*
* @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 {
* </pre>
*
* 当末位是":"时去除之不存在毫秒时
*
*
* @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();

View File

@ -157,7 +157,8 @@ public class Assert {
* <pre class="code">
* Assert.notEmpty(name, "Name must not be empty");
* </pre>
*
*
* @param <T> 字符串类型
* @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 extends CharSequence> 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 {
* <pre class="code">
* Assert.notEmpty(name);
* </pre>
*
*
* @param <T> 字符串类型
* @param text 被检查字符串
* @return 被检查的字符串
* @see StrUtil#isNotEmpty(CharSequence)
* @throws IllegalArgumentException 被检查字符串为空
*/
public static String notEmpty(String text) throws IllegalArgumentException {
public static <T extends CharSequence> 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 {
* <pre class="code">
* Assert.notBlank(name, "Name must not be blank");
* </pre>
*
*
* @param <T> 字符串类型
* @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 extends CharSequence> 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 {
* <pre class="code">
* Assert.notBlank(name, "Name must not be blank");
* </pre>
*
*
* @param <T> 字符串类型
* @param text 被检查字符串
* @return 非空字符串
* @see StrUtil#isNotBlank(CharSequence)
* @throws IllegalArgumentException 被检查字符串为空白
*/
public static String notBlank(String text) throws IllegalArgumentException {
public static <T extends CharSequence> 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");
}

View File

@ -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);
}

View File

@ -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;
/**
* 数字工具类<br>
* 对于精确值计算应该使用 {@link BigDecimal}<br>
@ -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;

View File

@ -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());
}
}