Merge remote-tracking branch 'origin/v5-dev' into v5-dev

This commit is contained in:
duandazhi 2021-03-19 09:23:20 +08:00
commit aa263733e0
106 changed files with 588 additions and 271 deletions

View File

@ -3,14 +3,31 @@
-------------------------------------------------------------------------------------------------------------
# 5.6.1 (2021-03-14)
# 5.6.2 (2021-03-18)
### 新特性
### Bug修复
-------------------------------------------------------------------------------------------------------------
# 5.6.1 (2021-03-18)
### 新特性
* 【crypto 】 SecureUtil去除final修饰符issue#1474@Github
* 【core 】 IoUtil增加lineIter方法
* 【core 】 新增函数式懒加载加载器(pr#275@Gitee)
* 【http 】 UserAgentUtil增加miniProgram判断(issue#1475@Github)
* 【db 】 增加Ignite数据库驱动识别
* 【core 】 DateUtil.parse支持带毫秒的UTC时间
* 【core 】 IdcardUtil.Idcard增加toStringpr#1487@Github
* 【core 】 ChineseDate增加getGregorianXXX方法issue#1481@Github
### Bug修复
* 【core 】 修复IoUtil.readBytes的FileInputStream中isClose参数失效问题issue#I3B7UD@Gitee
* 【core 】 修复DataUnit中KB不大写的问题
* 【json 】 修复JSONUtil.getByPath类型错误问题issue#I3BSDF@Gitee
* 【core 】 修复BeanUtil.toBean提供null未返回null的问题issue#I3BQPV@Gitee
* 【core 】 修复ModifierUtil#modifiersToInt中逻辑判断问题issue#1486@Github
-------------------------------------------------------------------------------------------------------------

View File

@ -125,19 +125,19 @@ Each module can be introduced individually, or all modules can be introduced by
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.6.1</version>
<version>5.6.2</version>
</dependency>
```
### Gradle
```
compile 'cn.hutool:hutool-all:5.6.1'
compile 'cn.hutool:hutool-all:5.6.2'
```
## Download
- [Maven1](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.6.1/)
- [Maven2](http://repo2.maven.org/maven2/cn/hutool/hutool-all/5.6.1/)
- [Maven1](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.6.2/)
- [Maven2](http://repo2.maven.org/maven2/cn/hutool/hutool-all/5.6.2/)
> note:
> Hutool 5.x supports JDK8+ and is not tested on Android platforms, and cannot guarantee that all tool classes or tool methods are available.
@ -199,6 +199,10 @@ If you think Hutool is good, you can donate to buy tshe author a pack of chili~,
## WeChat Official Account
Welcome to the official account of Hutool cooperation.
#### Welcome to the official account of Hutool cooperation.
![Java2B](https://cdn.jsdelivr.net/gh/looly/hutool-site/images/qrcode.jpg)
![Java2B](https://cdn.jsdelivr.net/gh/looly/hutool-site/images/qrcode.jpg)
#### Welcome to organization Dromara
![Dromara](https://dromara.org/img/qrcode/qrcode_1.png)

View File

@ -123,20 +123,20 @@ Hutool的存在就是为了减少代码搜索成本避免网络上参差不
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.6.1</version>
<version>5.6.2</version>
</dependency>
```
### Gradle
```
compile 'cn.hutool:hutool-all:5.6.1'
compile 'cn.hutool:hutool-all:5.6.2'
```
### 非Maven项目
点击以下任一链接,下载`hutool-all-X.X.X.jar`即可:
- [Maven中央库](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.6.1/)
- [Maven中央库](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.6.2/)
> 注意
> Hutool 5.x支持JDK8+对Android平台没有测试不能保证所有工具类或工具方法可用。
@ -207,6 +207,10 @@ Hutool欢迎任何人为Hutool添砖加瓦贡献代码不过维护者是
## 公众号
欢迎关注Hutool合作的公众号
#### 欢迎关注Hutool合作的公众号
![Java2B](https://cdn.jsdelivr.net/gh/looly/hutool-site/images/qrcode.jpg)
![Java2B](https://cdn.jsdelivr.net/gh/looly/hutool-site/images/qrcode.jpg)
#### Dromara开源组织公众号
![Dromara](https://dromara.org/img/qrcode/qrcode_1.png)

View File

@ -1 +1 @@
5.6.1
5.6.2

View File

@ -1 +1 @@
var version = '5.6.1'
var version = '5.6.2'

View File

@ -9,7 +9,7 @@
<parent>
<groupId>cn.hutool</groupId>
<artifactId>hutool-parent</artifactId>
<version>5.6.1-SNAPSHOT</version>
<version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>hutool-all</artifactId>

View File

@ -9,7 +9,7 @@
<parent>
<groupId>cn.hutool</groupId>
<artifactId>hutool-parent</artifactId>
<version>5.6.1-SNAPSHOT</version>
<version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>hutool-aop</artifactId>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>cn.hutool</groupId>
<artifactId>hutool-parent</artifactId>
<version>5.6.1-SNAPSHOT</version>
<version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>hutool-bloomFilter</artifactId>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>cn.hutool</groupId>
<artifactId>hutool-parent</artifactId>
<version>5.6.1-SNAPSHOT</version>
<version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>hutool-bom</artifactId>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>cn.hutool</groupId>
<artifactId>hutool-parent</artifactId>
<version>5.6.1-SNAPSHOT</version>
<version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>hutool-cache</artifactId>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>cn.hutool</groupId>
<artifactId>hutool-parent</artifactId>
<version>5.6.1-SNAPSHOT</version>
<version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>hutool-captcha</artifactId>

View File

@ -9,7 +9,7 @@
<parent>
<groupId>cn.hutool</groupId>
<artifactId>hutool-parent</artifactId>
<version>5.6.1-SNAPSHOT</version>
<version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>hutool-core</artifactId>

View File

@ -544,6 +544,9 @@ public class BeanUtil {
* @since 5.2.4
*/
public static <T> T toBean(Object source, Class<T> clazz, CopyOptions options) {
if(null == source){
return null;
}
final T target = ReflectUtil.newInstanceIfPossible(clazz);
copyProperties(source, target, options);
return target;
@ -559,6 +562,9 @@ public class BeanUtil {
* @return Bean
*/
public static <T> T toBean(Class<T> beanClass, ValueProvider<String> valueProvider, CopyOptions copyOptions) {
if (null == beanClass || null == valueProvider) {
return null;
}
return fillBean(ReflectUtil.newInstanceIfPossible(beanClass), valueProvider, copyOptions);
}
@ -600,6 +606,9 @@ public class BeanUtil {
* @return Map
*/
public static Map<String, Object> beanToMap(Object bean, boolean isToUnderlineCase, boolean ignoreNullValue) {
if (null == bean) {
return null;
}
return beanToMap(bean, new LinkedHashMap<>(), isToUnderlineCase, ignoreNullValue);
}
@ -614,7 +623,7 @@ public class BeanUtil {
* @since 3.2.3
*/
public static Map<String, Object> beanToMap(Object bean, Map<String, Object> targetMap, final boolean isToUnderlineCase, boolean ignoreNullValue) {
if (bean == null) {
if (null == bean) {
return null;
}
@ -639,7 +648,7 @@ public class BeanUtil {
* @since 4.0.5
*/
public static Map<String, Object> beanToMap(Object bean, Map<String, Object> targetMap, boolean ignoreNullValue, Editor<String> keyEditor) {
if (bean == null) {
if (null == bean) {
return null;
}

View File

@ -1,6 +1,6 @@
/**
* 集合以及Iterator封装包括集合工具CollUtilIterator和Iterable工具IterUtil
*
*
* @author looly
*
*/

View File

@ -5,7 +5,7 @@ import java.util.Comparator;
/**
* 针对 {@link Comparable}对象的默认比较器
*
*
* @param <E> 比较对象类型
* @author Looly
* @since 3.0.7
@ -25,7 +25,7 @@ public class ComparableComparator<E extends Comparable<? super E>> implements Co
/**
* 比较两个{@link Comparable}对象
*
*
* <pre>
* obj1.compareTo(obj2)
* </pre>

View File

@ -13,19 +13,19 @@ public class ComparatorException extends RuntimeException{
public ComparatorException(Throwable e) {
super(ExceptionUtil.getMessage(e), e);
}
public ComparatorException(String message) {
super(message);
}
public ComparatorException(String messageTemplate, Object... params) {
super(StrUtil.format(messageTemplate, params));
}
public ComparatorException(String message, Throwable throwable) {
super(message, throwable);
}
public ComparatorException(Throwable throwable, String messageTemplate, Object... params) {
super(StrUtil.format(messageTemplate, params), throwable);
}

View File

@ -12,7 +12,7 @@ import cn.hutool.core.util.StrUtil;
/**
* Bean字段排序器<br>
* 参阅feilong-core中的PropertyComparator
*
*
* @author Looly
*
* @param <T> 被比较的Bean
@ -24,7 +24,7 @@ public class FieldComparator<T> implements Comparator<T>, Serializable {
/**
* 构造
*
*
* @param beanClass Bean类
* @param fieldName 字段名
*/

View File

@ -7,7 +7,7 @@ import java.util.Locale;
/**
* 按照GBK拼音顺序对给定的汉字字符串排序
*
*
* @author looly
* @since 4.0.8
*/

View File

@ -9,20 +9,20 @@ import java.util.Comparator;
/**
* Bean属性排序器<br>
* 支持读取Bean多层次下的属性
*
*
* @author Looly
*
* @param <T> 被比较的Bean
*/
public class PropertyComparator<T> implements Comparator<T>, Serializable {
private static final long serialVersionUID = 9157326766723846313L;
private final String property;
private final boolean isNullGreater;
/**
* 构造
*
*
* @param property 属性名
*/
public PropertyComparator(String property) {
@ -31,7 +31,7 @@ public class PropertyComparator<T> implements Comparator<T>, Serializable {
/**
* 构造
*
*
* @param property 属性名
* @param isNullGreater null值是否排在后从小到大排序
*/

View File

@ -5,7 +5,7 @@ import java.util.Comparator;
/**
* 反转比较器
*
*
* @author Looly
*
* @param <E> 被比较对象类型

View File

@ -14,7 +14,7 @@ import java.util.List;
* 排序时版本从小到大排序即比较时小版本在前大版本在后<br>
* 支持如1.3.20.86.82.201601018.5a/8.5c等版本形式<br>
* 参考https://www.cnblogs.com/shihaiming/p/6286575.html
*
*
* @author Looly
* @since 4.0.2
*/
@ -44,7 +44,7 @@ public class VersionComparator implements Comparator<String>, Serializable {
* compare("1.13.0", "1.12.1c") &gt; 0
* compare("V0.0.20170102", "V0.0.20170101") &gt; 0
* </pre>
*
*
* @param version1 版本1
* @param version2 版本2
*/

View File

@ -1,6 +1,6 @@
/**
* 各种比较器Comparator实现和封装
*
*
* @author looly
*
*/

View File

@ -11,17 +11,17 @@ import java.util.Map;
/**
* 抽象转换器提供通用的转换逻辑同时通过convertInternal实现对应类型的专属逻辑<br>
* 转换器不会抛出转换异常转换失败时会返回{@code null}
*
*
* @author Looly
*
*/
public abstract class AbstractConverter<T> implements Converter<T>, Serializable {
private static final long serialVersionUID = 1L;
/**
* 不抛异常转换<br>
* 当转换失败时返回默认值
*
*
* @param value 被转换的值
* @param defaultValue 默认值
* @return 转换后的值
@ -66,12 +66,12 @@ public abstract class AbstractConverter<T> implements Converter<T>, Serializable
/**
* 内部转换器 {@link AbstractConverter#convert(Object, Object)} 调用实现基本转换逻辑<br>
* 内部转换器转换后如果转换失败可以做如下操作处理结果都为返回默认值
*
*
* <pre>
* 1返回{@code null}
* 1返回{@code null}
* 2抛出一个{@link RuntimeException}异常
* </pre>
*
*
* @param value
* @return 转换后的类型
*/
@ -80,13 +80,13 @@ public abstract class AbstractConverter<T> implements Converter<T>, Serializable
/**
* 值转为String用于内部转换中需要使用String中转的情况<br>
* 转换规则为
*
*
* <pre>
* 1字符串类型将被强转
* 2数组将被转换为逗号分隔的字符串
* 3其它类型将调用默认的toString()方法
* </pre>
*
*
* @param value
* @return String
*/
@ -107,7 +107,7 @@ public abstract class AbstractConverter<T> implements Converter<T>, Serializable
/**
* 获得此类实现类的泛型类型
*
*
* @return 此类的泛型类型可能为{@code null}
*/
@SuppressWarnings("unchecked")

View File

@ -10,12 +10,12 @@ import java.util.concurrent.ConcurrentHashMap;
*/
public enum BasicType {
BYTE, SHORT, INT, INTEGER, LONG, DOUBLE, FLOAT, BOOLEAN, CHAR, CHARACTER, STRING;
/** 包装类型为Key原始类型为Value例如 Integer.class =》 int.class. */
public static final Map<Class<?>, Class<?>> WRAPPER_PRIMITIVE_MAP = new ConcurrentHashMap<>(8);
/** 原始类型为Key包装类型为Value例如 int.class =》 Integer.class. */
public static final Map<Class<?>, Class<?>> PRIMITIVE_WRAPPER_MAP = new ConcurrentHashMap<>(8);
static {
WRAPPER_PRIMITIVE_MAP.put(Boolean.class, boolean.class);
WRAPPER_PRIMITIVE_MAP.put(Byte.class, byte.class);
@ -30,7 +30,7 @@ public enum BasicType {
PRIMITIVE_WRAPPER_MAP.put(entry.getValue(), entry.getKey());
}
}
/**
* 原始类转为包装类非原始类返回原类
* @param clazz 原始类
@ -43,7 +43,7 @@ public enum BasicType {
Class<?> result = PRIMITIVE_WRAPPER_MAP.get(clazz);
return (null == result) ? clazz : result;
}
/**
* 包装类转为原始类非包装类返回原类
* @param clazz 包装类

View File

@ -13,19 +13,19 @@ public class ConvertException extends RuntimeException{
public ConvertException(Throwable e) {
super(ExceptionUtil.getMessage(e), e);
}
public ConvertException(String message) {
super(message);
}
public ConvertException(String messageTemplate, Object... params) {
super(StrUtil.format(messageTemplate, params));
}
public ConvertException(String message, Throwable throwable) {
super(message, throwable);
}
public ConvertException(Throwable throwable, String messageTemplate, Object... params) {
super(StrUtil.format(messageTemplate, params), throwable);
}

View File

@ -2,7 +2,7 @@ package cn.hutool.core.convert;
/**
* 转换器接口实现类型转换
*
*
* @param <T> 转换到的目标类型
* @author Looly
*/
@ -11,7 +11,7 @@ public interface Converter<T> {
/**
* 转换为指定类型<br>
* 如果类型无法确定将读取默认值的类型做为目标类型
*
*
* @param value 原始值
* @param defaultValue 默认值
* @return 转换后的值

View File

@ -7,7 +7,7 @@ import cn.hutool.core.util.BooleanUtil;
/**
* {@link AtomicBoolean}转换器
*
*
* @author Looly
* @since 3.0.8
*/

View File

@ -7,7 +7,7 @@ import java.util.concurrent.atomic.AtomicIntegerArray;
/**
* {@link AtomicIntegerArray}转换器
*
*
* @author Looly
* @since 5.4.5
*/

View File

@ -7,7 +7,7 @@ import java.util.concurrent.atomic.AtomicLongArray;
/**
* {@link AtomicLongArray}转换器
*
*
* @author Looly
* @since 5.4.5
*/

View File

@ -9,17 +9,17 @@ import cn.hutool.core.util.TypeUtil;
/**
* {@link AtomicReference}转换器
*
*
* @author Looly
* @since 3.0.8
*/
@SuppressWarnings("rawtypes")
public class AtomicReferenceConverter extends AbstractConverter<AtomicReference> {
private static final long serialVersionUID = 1L;
@Override
protected AtomicReference<?> convertInternal(Object value) {
//尝试将值转换为Reference泛型的类型
Object targetValue = null;
final Type paramType = TypeUtil.getTypeArgument(AtomicReference.class);
@ -29,7 +29,7 @@ public class AtomicReferenceConverter extends AbstractConverter<AtomicReference>
if(null == targetValue){
targetValue = value;
}
return new AtomicReference<>(targetValue);
}

View File

@ -21,7 +21,7 @@ import java.util.Map;
* Bean = Bean
* ValueProvider = Bean
* </pre>
*
*
* @param <T> Bean类型
* @author Looly
* @since 4.0.2
@ -32,10 +32,10 @@ public class BeanConverter<T> extends AbstractConverter<T> {
private final Type beanType;
private final Class<T> beanClass;
private final CopyOptions copyOptions;
/**
* 构造默认转换选项注入失败的字段忽略
*
*
* @param beanType 转换成的目标Bean类型
*/
public BeanConverter(Type beanType) {
@ -44,16 +44,16 @@ public class BeanConverter<T> extends AbstractConverter<T> {
/**
* 构造默认转换选项注入失败的字段忽略
*
*
* @param beanClass 转换成的目标Bean类
*/
public BeanConverter(Class<T> beanClass) {
this(beanClass, CopyOptions.create().setIgnoreError(true));
}
/**
* 构造
*
*
* @param beanType 转换成的目标Bean类
* @param copyOptions Bean转换选项参数
*/

View File

@ -9,7 +9,7 @@ import cn.hutool.core.util.StrUtil;
/**
* 日期转换器
*
*
* @author Looly
*
*/
@ -21,7 +21,7 @@ public class CalendarConverter extends AbstractConverter<Calendar> {
/**
* 获取日期格式
*
*
* @return 设置日期格式
*/
public String getFormat() {
@ -30,7 +30,7 @@ public class CalendarConverter extends AbstractConverter<Calendar> {
/**
* 设置日期格式
*
*
* @param format 日期格式
*/
public void setFormat(String format) {

View File

@ -5,7 +5,7 @@ import cn.hutool.core.convert.ConvertException;
/**
* 强转转换器
*
*
* @author Looly
* @param <T> 强制转换到的类型
* @since 4.0.2

View File

@ -6,7 +6,7 @@ import cn.hutool.core.util.StrUtil;
/**
* 字符转换器
*
*
* @author Looly
*
*/

View File

@ -10,7 +10,7 @@ import java.util.Collection;
/**
* 各种集合类转换器
*
*
* @author Looly
* @since 3.0.8
*/
@ -31,7 +31,7 @@ public class CollectionConverter implements Converter<Collection<?>> {
// ---------------------------------------------------------------------------------------------- Constractor start
/**
* 构造
*
*
* @param collectionType 集合类型
*/
public CollectionConverter(Type collectionType) {
@ -40,7 +40,7 @@ public class CollectionConverter implements Converter<Collection<?>> {
/**
* 构造
*
*
* @param collectionType 集合类型
*/
public CollectionConverter(Class<?> collectionType) {
@ -49,7 +49,7 @@ public class CollectionConverter implements Converter<Collection<?>> {
/**
* 构造
*
*
* @param collectionType 集合类型
* @param elementType 集合元素类型
*/
@ -67,7 +67,7 @@ public class CollectionConverter implements Converter<Collection<?>> {
/**
* 内部转换
*
*
* @param value
* @return 转换后的集合对象
*/

View File

@ -6,7 +6,7 @@ import cn.hutool.core.convert.AbstractConverter;
/**
* 货币{@link Currency} 转换器
*
*
* @author Looly
* @since 3.0.8
*/

View File

@ -6,9 +6,9 @@ import java.time.Duration;
import java.time.temporal.TemporalAmount;
/**
*
*
* {@link Duration}对象转换器
*
*
* @author Looly
* @since 5.0.0
*/

View File

@ -4,7 +4,7 @@ import cn.hutool.core.convert.AbstractConverter;
/**
* 泛型枚举转换器
*
*
* @param <E> 枚举类类型
* @author Looly
* @since 4.0.2
@ -15,10 +15,10 @@ public class GenericEnumConverter<E extends Enum<E>> extends AbstractConverter<E
private static final long serialVersionUID = 1L;
private final Class<E> enumClass;
/**
* 构造
*
*
* @param enumClass 转换成的目标Enum类
*/
public GenericEnumConverter(Class<E> enumClass) {

View File

@ -6,10 +6,10 @@ import cn.hutool.core.convert.AbstractConverter;
import cn.hutool.core.util.StrUtil;
/**
*
*
* {@link Locale}对象转换器<br>
* 只提供String转换支持
*
*
* @author Looly
* @since 4.5.2
*/

View File

@ -14,7 +14,7 @@ import java.util.Objects;
/**
* {@link Map} 转换器
*
*
* @author Looly
* @since 3.0.8
*/
@ -30,7 +30,7 @@ public class MapConverter extends AbstractConverter<Map<?, ?>> {
/**
* 构造Map的key和value泛型类型自动获取
*
*
* @param mapType Map类型
*/
public MapConverter(Type mapType) {
@ -39,7 +39,7 @@ public class MapConverter extends AbstractConverter<Map<?, ?>> {
/**
* 构造
*
*
* @param mapType Map类型
* @param keyType 键类型
* @param valueType 值类型
@ -77,7 +77,7 @@ public class MapConverter extends AbstractConverter<Map<?, ?>> {
/**
* Map转Map
*
*
* @param srcMap 源Map
* @param targetMap 目标Map
*/

View File

@ -5,9 +5,9 @@ import cn.hutool.core.convert.AbstractConverter;
import java.util.Optional;
/**
*
*
* {@link Optional}对象转换器
*
*
* @author Looly
* @since 5.0.0
*/

View File

@ -22,15 +22,15 @@ public class PathConverter extends AbstractConverter<Path>{
if(value instanceof URI){
return Paths.get((URI)value);
}
if(value instanceof URL){
return Paths.get(((URL)value).toURI());
}
if(value instanceof File){
return ((File)value).toPath();
}
return Paths.get(convertToStr(value));
} catch (Exception e) {
// Ignore Exception

View File

@ -6,9 +6,9 @@ import java.time.Period;
import java.time.temporal.TemporalAmount;
/**
*
*
* {@link Period}对象转换器
*
*
* @author Looly
* @since 5.0.0
*/

View File

@ -12,16 +12,16 @@ import java.lang.reflect.Type;
/**
* {@link Reference}转换器
*
*
* @author Looly
* @since 3.0.8
*/
@SuppressWarnings("rawtypes")
public class ReferenceConverter extends AbstractConverter<Reference> {
private static final long serialVersionUID = 1L;
private final Class<? extends Reference> targetType;
/**
* 构造
* @param targetType {@link Reference}实现类型
@ -33,7 +33,7 @@ public class ReferenceConverter extends AbstractConverter<Reference> {
@SuppressWarnings("unchecked")
@Override
protected Reference<?> convertInternal(Object value) {
//尝试将值转换为Reference泛型的类型
Object targetValue = null;
final Type paramType = TypeUtil.getTypeArgument(targetType);
@ -43,13 +43,13 @@ public class ReferenceConverter extends AbstractConverter<Reference> {
if(null == targetValue){
targetValue = value;
}
if(this.targetType == WeakReference.class){
return new WeakReference(targetValue);
}else if(this.targetType == SoftReference.class){
return new SoftReference(targetValue);
}
throw new UnsupportedOperationException(StrUtil.format("Unsupport Reference type: {}", this.targetType.getName()));
}

View File

@ -9,7 +9,7 @@ import cn.hutool.core.util.ObjectUtil;
/**
* {@link StackTraceElement} 转换器<br>
* 只支持Map方式转换
*
*
* @author Looly
* @since 3.0.8
*/

View File

@ -20,7 +20,7 @@ public class URIConverter extends AbstractConverter<URI>{
if(value instanceof File){
return ((File)value).toURI();
}
if(value instanceof URL){
return ((URL)value).toURI();
}

View File

@ -20,7 +20,7 @@ public class URLConverter extends AbstractConverter<URL>{
if(value instanceof File){
return ((File)value).toURI().toURL();
}
if(value instanceof URI){
return ((URI)value).toURL();
}

View File

@ -6,7 +6,7 @@ import cn.hutool.core.convert.AbstractConverter;
/**
* UUID对象转换器转换器
*
*
* @author Looly
* @since 4.0.10
*

View File

@ -1,6 +1,6 @@
/**
* 各种类型转换的实现类其都为Converter接口的实现用于将未知的Object类型转换为指定类型
*
*
* @author looly
*
*/

View File

@ -1,6 +1,6 @@
/**
* 万能类型转换器以及各种类型转换的实现类其中Convert为转换器入口提供各种toXXX方法和convert方法
*
*
* @author looly
*
*/

View File

@ -7,6 +7,7 @@ import cn.hutool.core.date.chinese.LunarFestival;
import cn.hutool.core.date.chinese.LunarInfo;
import cn.hutool.core.util.StrUtil;
import java.util.Calendar;
import java.util.Date;
@ -151,6 +152,16 @@ public class ChineseDate {
return this.year;
}
/**
* 获取公历的年
*
* @return 公历年
* @since 5.6.1
*/
public int getGregorianYear(){
return this.gyear;
}
/**
* 获取农历的月从1开始计数
*
@ -161,6 +172,26 @@ public class ChineseDate {
return this.month;
}
/**
* 获取公历的月从1开始计数
*
* @return 公历月
* @since 5.6.1
*/
public int getGregorianMonthBase1(){
return this.gmonth;
}
/**
* 获取公历的月从0开始计数
*
* @return 公历月
* @since 5.6.1
*/
public int getGregorianMonth(){
return this.gmonth -1;
}
/**
* 当前农历月份是否为闰月
*
@ -200,6 +231,16 @@ public class ChineseDate {
return this.day;
}
/**
* 获取公历的日
*
* @return 公历日
* @since 5.6.1
*/
public int getGregorianDay(){
return this.gday;
}
/**
* 获得农历日
*
@ -223,6 +264,28 @@ public class ChineseDate {
}
}
/**
* 获取公历的Date
*
* @return 公历Date
* @since 5.6.1
*/
public Date getGregorianDate(){
return DateUtil.date(getGregorianCalendar());
}
/**
* 获取公历的Calendar
*
* @return 公历Calendar
* @since 5.6.1
*/
public Calendar getGregorianCalendar(){
final Calendar calendar = CalendarUtil.calendar();
//noinspection MagicConstant
calendar.set(this.gyear, getGregorianMonth(), this.gday, 0, 0, 0);
return calendar;
}
/**
* 获得节日
@ -347,4 +410,4 @@ public class ChineseDate {
// ------------------------------------------------------- private method end
}
}

View File

@ -8,7 +8,7 @@ import java.util.Date;
/**
* 日期间隔
*
*
* @author Looly
*
*/
@ -23,7 +23,7 @@ public class DateBetween implements Serializable{
/**
* 创建<br>
* 在前的日期做为起始时间在后的做为结束时间间隔只保留绝对值正数
*
*
* @param begin 起始时间
* @param end 结束时间
* @return DateBetween
@ -36,7 +36,7 @@ public class DateBetween implements Serializable{
/**
* 创建<br>
* 在前的日期做为起始时间在后的做为结束时间间隔只保留绝对值正数
*
*
* @param begin 起始时间
* @param end 结束时间
* @param isAbs 日期间隔是否只保留绝对值正数
@ -50,7 +50,7 @@ public class DateBetween implements Serializable{
/**
* 构造<br>
* 在前的日期做为起始时间在后的做为结束时间间隔只保留绝对值正数
*
*
* @param begin 起始时间
* @param end 结束时间
*/
@ -61,7 +61,7 @@ public class DateBetween implements Serializable{
/**
* 构造<br>
* 在前的日期做为起始时间在后的做为结束时间
*
*
* @param begin 起始时间
* @param end 结束时间
* @param isAbs 日期间隔是否只保留绝对值正数
@ -70,7 +70,7 @@ public class DateBetween implements Serializable{
public DateBetween(Date begin, Date end, boolean isAbs) {
Assert.notNull(begin, "Begin date is null !");
Assert.notNull(end, "End date is null !");
if (isAbs && begin.after(end)) {
// 间隔只为正数的情况下如果开始日期晚于结束日期置换之
this.begin = end;
@ -84,7 +84,7 @@ public class DateBetween implements Serializable{
/**
* 判断两个日期相差的时长<br>
* 返回 给定单位的时长差
*
*
* @param unit 相差的单位相差 {@link DateUnit#DAY}小时{@link DateUnit#HOUR}
* @return 时长差
*/
@ -96,7 +96,7 @@ public class DateBetween implements Serializable{
/**
* 计算两个日期相差月数<br>
* 在非重置情况下如果起始日期的天大于结束日期的天月数要少算1不足1个月
*
*
* @param isReset 是否重置时间为起始时间重置天时分秒
* @return 相差月数
* @since 3.0.8
@ -123,7 +123,7 @@ public class DateBetween implements Serializable{
/**
* 计算两个日期相差年数<br>
* 在非重置情况下如果起始日期的月大于结束日期的月年数要少算1不足1年
*
*
* @param isReset 是否重置时间为起始时间重置月天时分秒
* @return 相差年数
* @since 3.0.8
@ -155,7 +155,7 @@ public class DateBetween implements Serializable{
/**
* 格式化输出时间差<br>
*
*
* @param level 级别
* @return 字符串
*/

View File

@ -13,19 +13,19 @@ public class DateException extends RuntimeException{
public DateException(Throwable e) {
super(ExceptionUtil.getMessage(e), e);
}
public DateException(String message) {
super(message);
}
public DateException(String messageTemplate, Object... params) {
super(StrUtil.format(messageTemplate, params));
}
public DateException(String message, Throwable throwable) {
super(message, throwable);
}
public DateException(Throwable throwable, String messageTemplate, Object... params) {
super(StrUtil.format(messageTemplate, params), throwable);
}

View File

@ -5,7 +5,7 @@ import java.util.Calendar;
/**
* 日期各个部分的枚举<br>
* 与Calendar相应值对应
*
*
* @author Looly
*
*/
@ -13,91 +13,91 @@ public enum DateField {
/**
* 世纪
*
*
* @see Calendar#ERA
*/
ERA(Calendar.ERA),
/**
*
*
*
* @see Calendar#YEAR
*/
YEAR(Calendar.YEAR),
/**
*
*
*
* @see Calendar#MONTH
*/
MONTH(Calendar.MONTH),
/**
* 一年中第几周
*
*
* @see Calendar#WEEK_OF_YEAR
*/
WEEK_OF_YEAR(Calendar.WEEK_OF_YEAR),
/**
* 一月中第几周
*
*
* @see Calendar#WEEK_OF_MONTH
*/
WEEK_OF_MONTH(Calendar.WEEK_OF_MONTH),
/**
* 一月中的第几天
*
*
* @see Calendar#DAY_OF_MONTH
*/
DAY_OF_MONTH(Calendar.DAY_OF_MONTH),
/**
* 一年中的第几天
*
*
* @see Calendar#DAY_OF_YEAR
*/
DAY_OF_YEAR(Calendar.DAY_OF_YEAR),
/**
* 周几1表示周日2表示周一
*
*
* @see Calendar#DAY_OF_WEEK
*/
DAY_OF_WEEK(Calendar.DAY_OF_WEEK),
/**
* 天所在的周是这个月的第几周
*
*
* @see Calendar#DAY_OF_WEEK_IN_MONTH
*/
DAY_OF_WEEK_IN_MONTH(Calendar.DAY_OF_WEEK_IN_MONTH),
/**
* 上午或者下午
*
*
* @see Calendar#AM_PM
*/
AM_PM(Calendar.AM_PM),
/**
* 小时用于12小时制
*
*
* @see Calendar#HOUR
*/
HOUR(Calendar.HOUR),
/**
* 小时用于24小时制
*
*
* @see Calendar#HOUR
*/
HOUR_OF_DAY(Calendar.HOUR_OF_DAY),
/**
* 分钟
*
*
* @see Calendar#MINUTE
*/
MINUTE(Calendar.MINUTE),
/**
*
*
*
* @see Calendar#SECOND
*/
SECOND(Calendar.SECOND),
/**
* 毫秒
*
*
* @see Calendar#MILLISECOND
*/
MILLISECOND(Calendar.MILLISECOND);
@ -115,7 +115,7 @@ public enum DateField {
/**
* {@link Calendar}相关值转换为DatePart枚举对象<br>
*
*
* @param calendarPartIntValue Calendar中关于Week的int值
* @return {@link DateField}
*/

View File

@ -7,13 +7,13 @@ import cn.hutool.core.util.ArrayUtil;
/**
* 日期修改器<br>
* 用于实现自定义某个日期字段的调整包括
*
*
* <pre>
* 1. 获取指定字段的起始时间
* 2. 获取指定字段的四舍五入时间
* 3. 获取指定字段的结束时间
* </pre>
*
*
* @author looly
*
*/
@ -31,7 +31,7 @@ public class DateModifier {
/**
* 修改日期
*
*
* @param calendar {@link Calendar}
* @param dateField 日期字段即保留到哪个日期字段
* @param modifyType 修改类型包括舍去四舍五入进一等
@ -87,7 +87,7 @@ public class DateModifier {
// -------------------------------------------------------------------------------------------------- Private method start
/**
* 修改日期字段值
*
*
* @param calendar {@link Calendar}
* @param field 字段{@link Calendar}
* @param modifyType {@link ModifyType}
@ -125,7 +125,7 @@ public class DateModifier {
/**
* 修改类型
*
*
* @author looly
*
*/

View File

@ -200,6 +200,15 @@ public class DatePattern {
*/
public static final FastDateFormat UTC_SIMPLE_FORMAT = FastDateFormat.getInstance(UTC_SIMPLE_PATTERN, TimeZone.getTimeZone("UTC"));
/**
* UTC时间yyyy-MM-dd'T'HH:mm:ss.SSS
*/
public static final String UTC_SIMPLE_MS_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSS";
/**
* UTC时间{@link FastDateFormat}yyyy-MM-dd'T'HH:mm:ss.SSS
*/
public static final FastDateFormat UTC_SIMPLE_MS_FORMAT = FastDateFormat.getInstance(UTC_SIMPLE_MS_PATTERN, TimeZone.getTimeZone("UTC"));
/**
* UTC时间yyyy-MM-dd'T'HH:mm:ss'Z'
*/

View File

@ -6,7 +6,7 @@ import java.util.Date;
/**
* 日期范围
*
*
* @author looly
* @since 4.1.0
*/
@ -15,7 +15,7 @@ public class DateRange extends Range<DateTime> {
/**
* 构造包含开始和结束日期时间
*
*
* @param start 起始日期时间
* @param end 结束日期时间
* @param unit 步进单位
@ -26,7 +26,7 @@ public class DateRange extends Range<DateTime> {
/**
* 构造包含开始和结束日期时间
*
*
* @param start 起始日期时间
* @param end 结束日期时间
* @param unit 步进单位
@ -38,7 +38,7 @@ public class DateRange extends Range<DateTime> {
/**
* 构造
*
*
* @param start 起始日期时间
* @param end 结束日期时间
* @param unit 步进单位

View File

@ -836,6 +836,9 @@ public class DateUtil extends CalendarUtil {
} 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);
}
}
// 没有更多匹配的时间格式

View File

@ -2,12 +2,12 @@ package cn.hutool.core.date;
/**
* 季度枚举
*
*
* @see #Q1
* @see #Q2
* @see #Q3
* @see #Q4
*
*
* @author zhfish(https://github.com/zhfish)
*
*/
@ -21,7 +21,7 @@ public enum Quarter {
Q3(3),
/** 第四季度 */
Q4(4);
// ---------------------------------------------------------------
private final int value;
@ -35,12 +35,12 @@ public enum Quarter {
/**
* 季度int转换为Season枚举对象<br>
*
*
* @see #Q1
* @see #Q2
* @see #Q3
* @see #Q4
*
*
* @param intValue 季度int表示
* @return {@link Quarter}
*/

View File

@ -11,12 +11,12 @@ import java.util.concurrent.TimeUnit;
* System.currentTimeMillis()的调用比new一个普通对象要耗时的多具体耗时高出多少我还没测试过有人说是100倍左右
* System.currentTimeMillis()之所以慢是因为去跟系统打了一次交道
* 后台定时更新时钟JVM退出时线程自动回收
*
*
* see http://git.oschina.net/yu120/sequence
* @author lry,looly
*/
public class SystemClock {
/** 时钟更新间隔,单位毫秒 */
private final long period;
/** 现在时刻的毫秒数 */
@ -50,7 +50,7 @@ public class SystemClock {
private long currentTimeMillis() {
return now;
}
//------------------------------------------------------------------------ static
/**
* 单例

View File

@ -5,7 +5,7 @@ import java.util.Calendar;
/**
* 星期枚举<br>
* 与Calendar中的星期int值对应
*
*
* @see #SUNDAY
* @see #MONDAY
* @see #TUESDAY
@ -13,7 +13,7 @@ import java.util.Calendar;
* @see #THURSDAY
* @see #FRIDAY
* @see #SATURDAY
*
*
* @author Looly
*
*/
@ -40,7 +40,7 @@ public enum Week {
/**
* 构造
*
*
* @param value 星期对应{@link Calendar} 中的Week值
*/
Week(int value) {
@ -49,16 +49,16 @@ public enum Week {
/**
* 获得星期对应{@link Calendar} 中的Week值
*
*
* @return 星期对应{@link Calendar} 中的Week值
*/
public int getValue() {
return this.value;
}
/**
* 转换为中文名
*
*
* @return 星期的中文名
* @since 3.3.0
*/
@ -68,7 +68,7 @@ public enum Week {
/**
* 转换为中文名
*
*
* @param weekNamePre 表示星期的前缀例如前缀为星期则返回结果为星期一前缀为结果为周一
* @return 星期的中文名
* @since 4.0.11
@ -96,7 +96,7 @@ public enum Week {
/**
* {@link Calendar}星期相关值转换为Week枚举对象<br>
*
*
* @see #SUNDAY
* @see #MONDAY
* @see #TUESDAY
@ -104,7 +104,7 @@ public enum Week {
* @see #THURSDAY
* @see #FRIDAY
* @see #SATURDAY
*
*
* @param calendarWeekIntValue Calendar中关于Week的int值
* @return {@link Week}
*/

View File

@ -5,7 +5,7 @@ import java.util.Date;
/**
* 星座 来自https://blog.csdn.net/u010758605/article/details/48317881
*
*
* @author looly
* @since 4.4.3
*/
@ -19,7 +19,7 @@ public class Zodiac {
/**
* 通过生日计算星座
*
*
* @param date 出生日期
* @return 星座名
*/
@ -29,7 +29,7 @@ public class Zodiac {
/**
* 通过生日计算星座
*
*
* @param calendar 出生日期
* @return 星座名
*/
@ -39,10 +39,10 @@ public class Zodiac {
}
return getZodiac(calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
}
/**
* 通过生日计算星座
*
*
* @param month 从0开始计数
* @param day
* @return 星座名
@ -54,7 +54,7 @@ public class Zodiac {
/**
* 通过生日计算星座
*
*
* @param month 从0开始计数{@link Month#getValue()}
* @param day
* @return 星座名
@ -67,7 +67,7 @@ public class Zodiac {
// ----------------------------------------------------------------------------------------------------------- 生肖
/**
* 通过生日计算生肖只计算1900年后出生的人
*
*
* @param date 出生日期年需农历
* @return 星座名
*/
@ -77,7 +77,7 @@ public class Zodiac {
/**
* 通过生日计算生肖只计算1900年后出生的人
*
*
* @param calendar 出生日期年需农历
* @return 星座名
*/
@ -90,7 +90,7 @@ public class Zodiac {
/**
* 计算生肖只计算1900年后出生的人
*
*
* @param year 农历年
* @return 生肖名
*/

View File

@ -1,6 +1,6 @@
/**
* 农历相关类汇总包括农历月天干地支农历节日24节气等
*
*
* @author looly
*
*/

View File

@ -6,14 +6,14 @@ import java.util.TimeZone;
public abstract class AbstractDateBasic implements DateBasic, Serializable {
private static final long serialVersionUID = 6333136319870641818L;
/** The pattern */
protected final String pattern;
/** The time zone. */
protected final TimeZone timeZone;
/** The locale. */
protected final Locale locale;
/**
* 构造内部使用
* @param pattern 使用{@link java.text.SimpleDateFormat} 相同的日期格式

View File

@ -5,7 +5,7 @@ import java.util.TimeZone;
/**
* 日期基本信息获取接口
*
*
* @author Looly
* @since 2.16.2
*/
@ -13,21 +13,21 @@ public interface DateBasic {
/**
* 获得日期格式化或者转换的格式
*
*
* @return {@link java.text.SimpleDateFormat}兼容的格式
*/
String getPattern();
/**
* 获得时区
*
*
* @return {@link TimeZone}
*/
TimeZone getTimeZone();
/**
* 获得 日期地理位置
*
*
* @return {@link Locale}
*/
Locale getLocale();

View File

@ -15,7 +15,7 @@ public interface DateParser extends DateBasic{
/**
* 将日期字符串解析并转换为 {@link Date} 对象<br>
* 等价于 {@link java.text.DateFormat#parse(String)}
*
*
* @param source 日期字符串
* @return {@link Date}
* @throws ParseException 转换异常被转换的字符串格式错误
@ -25,7 +25,7 @@ public interface DateParser extends DateBasic{
/**
* 将日期字符串解析并转换为 {@link Date} 对象<br>
* 等价于 {@link java.text.DateFormat#parse(String, ParsePosition)}
*
*
* @param source 日期字符串
* @param pos {@link ParsePosition}
* @return {@link Date}
@ -34,8 +34,8 @@ public interface DateParser extends DateBasic{
/**
* 根据给定格式转换日期字符串
* Updates the Calendar with parsed fields. Upon success, the ParsePosition index is updated to indicate how much of the source text was consumed.
* Not all source text needs to be consumed.
* Updates the Calendar with parsed fields. Upon success, the ParsePosition index is updated to indicate how much of the source text was consumed.
* Not all source text needs to be consumed.
* Upon parse failure, ParsePosition error index is updated to the offset of the source text which does not match the supplied format.
*
* @param source 被转换的日期字符串
@ -48,7 +48,7 @@ public interface DateParser extends DateBasic{
/**
* 将日期字符串解析并转换为 {@link Date} 对象<br>
*
*
* @param source A <code>String</code> whose beginning should be parsed.
* @return a <code>java.util.Date</code> object
* @throws ParseException if the beginning of the specified string cannot be parsed.
@ -58,7 +58,7 @@ public interface DateParser extends DateBasic{
/**
* 根据 {@link ParsePosition} 给定将日期字符串解析并转换为 {@link Date} 对象<br>
*
*
* @param source A <code>String</code> whose beginning should be parsed.
* @param pos the parse position
* @return a <code>java.util.Date</code> object

View File

@ -22,7 +22,7 @@ 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
*/
@ -51,7 +51,7 @@ public class FastDateFormat extends Format implements DateParser, DatePrinter {
// -----------------------------------------------------------------------
/**
* 获得 FastDateFormat实例使用默认格式和地区
*
*
* @return FastDateFormat
*/
public static FastDateFormat getInstance() {
@ -61,7 +61,7 @@ public class FastDateFormat extends Format implements DateParser, DatePrinter {
/**
* 获得 FastDateFormat 实例使用默认地区<br>
* 支持缓存
*
*
* @param pattern 使用{@link java.text.SimpleDateFormat} 相同的日期格式
* @return FastDateFormat
* @throws IllegalArgumentException 日期格式问题
@ -73,7 +73,7 @@ public class FastDateFormat extends Format implements DateParser, DatePrinter {
/**
* 获得 FastDateFormat 实例<br>
* 支持缓存
*
*
* @param pattern 使用{@link java.text.SimpleDateFormat} 相同的日期格式
* @param timeZone 时区{@link TimeZone}
* @return FastDateFormat
@ -99,7 +99,7 @@ public class FastDateFormat extends Format implements DateParser, DatePrinter {
/**
* 获得 FastDateFormat 实例<br>
* 支持缓存
*
*
* @param pattern 使用{@link java.text.SimpleDateFormat} 相同的日期格式
* @param timeZone 时区{@link TimeZone}
* @param locale {@link Locale} 日期地理位置

View File

@ -22,7 +22,7 @@ import java.util.concurrent.ConcurrentMap;
*/
public class FastDatePrinter extends AbstractDateBasic implements DatePrinter {
private static final long serialVersionUID = -6305750172255764887L;
/** 规则列表. */
private transient Rule[] rules;
/** 估算最大长度. */
@ -32,7 +32,7 @@ public class FastDatePrinter extends AbstractDateBasic implements DatePrinter {
// -----------------------------------------------------------------------
/**
* 构造内部使用<br>
*
*
* @param pattern 使用{@link java.text.SimpleDateFormat} 相同的日期格式
* @param timeZone 非空时区{@link TimeZone}
* @param locale 非空{@link Locale} 日期地理位置
@ -289,7 +289,7 @@ public class FastDatePrinter extends AbstractDateBasic implements DatePrinter {
* <p>
* Formats a {@code Date}, {@code Calendar} or {@code Long} (milliseconds) object.
* </p>
*
*
* @param obj the object to format
* @return The formatted value.
*/
@ -347,10 +347,10 @@ public class FastDatePrinter extends AbstractDateBasic implements DatePrinter {
}
return applyRules(calendar, buf);
}
/**
* Creates a String representation of the given Calendar by applying the rules of this printer to it.
*
*
* @param c the Calender to apply the rules to.
* @return a String representation of the given Calendar.
*/

View File

@ -14,7 +14,7 @@ import java.util.concurrent.ConcurrentMap;
/**
* 日期格式化器缓存<br>
* Thanks to Apache Commons Lang 3.5
*
*
* @since 2.16.2
*/
abstract class FormatCache<F extends Format> {
@ -38,7 +38,7 @@ abstract class FormatCache<F extends Format> {
/**
* 使用 pattern, time zone and locale 获得对应的 格式化器
*
*
* @param pattern 非空日期格式使用与 {@link java.text.SimpleDateFormat}相同格式
* @param timeZone 时区默认当前时区
* @param locale 地区默认使用当前地区
@ -69,7 +69,7 @@ abstract class FormatCache<F extends Format> {
/**
* 创建格式化器
*
*
* @param pattern 非空日期格式使用与 {@link java.text.SimpleDateFormat}相同格式
* @param timeZone 时区默认当前时区
* @param locale 地区默认使用当前地区
@ -82,7 +82,7 @@ abstract class FormatCache<F extends Format> {
* <p>
* Gets a date/time formatter instance using the specified style, time zone and locale.
* </p>
*
*
* @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT, null indicates no date in format
* @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT, null indicates no time in format
* @param timeZone optional time zone, overrides time zone of formatted date, null means use default Locale
@ -103,7 +103,7 @@ abstract class FormatCache<F extends Format> {
* <p>
* Gets a date/time formatter instance using the specified style, time zone and locale.
* </p>
*
*
* @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT
* @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT
* @param timeZone optional time zone, overrides time zone of formatted date, null means use default Locale
@ -120,7 +120,7 @@ abstract class FormatCache<F extends Format> {
* <p>
* Gets a date formatter instance using the specified style, time zone and locale.
* </p>
*
*
* @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT
* @param timeZone optional time zone, overrides time zone of formatted date, null means use default Locale
* @param locale optional locale, overrides system locale
@ -136,7 +136,7 @@ abstract class FormatCache<F extends Format> {
* <p>
* Gets a time formatter instance using the specified style, time zone and locale.
* </p>
*
*
* @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT
* @param timeZone optional time zone, overrides time zone of formatted date, null means use default Locale
* @param locale optional locale, overrides system locale
@ -152,7 +152,7 @@ abstract class FormatCache<F extends Format> {
* <p>
* Gets a date/time format for the specified styles and locale.
* </p>
*
*
* @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT, null indicates no date in format
* @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT, null indicates no time in format
* @param locale The non-null locale of the desired format

View File

@ -1,6 +1,6 @@
/**
* 提供线程安全的日期格式的格式化和解析实现
*
*
* @author looly
*
*/

View File

@ -1,6 +1,6 @@
/**
* 日期封装日期的核心为DateTime类DateUtil提供日期操作的入口
*
*
* @author looly
*
*/

View File

@ -4,7 +4,7 @@ import cn.hutool.core.util.StrUtil;
/**
* 依赖异常
*
*
* @author xiaoleilu
* @since 4.0.10
*/

View File

@ -4,7 +4,7 @@ import cn.hutool.core.util.StrUtil;
/**
* 未初始化异常
*
*
* @author xiaoleilu
*/
public class NotInitedException extends RuntimeException {

View File

@ -4,7 +4,7 @@ import cn.hutool.core.util.StrUtil;
/**
* 带有状态码的异常
*
*
* @author xiaoleilu
*
*/

View File

@ -12,19 +12,19 @@ public class UtilException extends RuntimeException{
public UtilException(Throwable e) {
super(ExceptionUtil.getMessage(e), e);
}
public UtilException(String message) {
super(message);
}
public UtilException(String messageTemplate, Object... params) {
super(StrUtil.format(messageTemplate, params));
}
public UtilException(String message, Throwable throwable) {
super(message, throwable);
}
public UtilException(Throwable throwable, String messageTemplate, Object... params) {
super(StrUtil.format(messageTemplate, params), throwable);
}

View File

@ -4,7 +4,7 @@ import cn.hutool.core.util.StrUtil;
/**
* 验证异常
*
*
* @author xiaoleilu
*/
public class ValidateException extends StatefulException {
@ -16,7 +16,7 @@ public class ValidateException extends StatefulException {
public ValidateException(String msg) {
super(msg);
}
public ValidateException(String messageTemplate, Object... params) {
super(StrUtil.format(messageTemplate, params));
}

View File

@ -44,7 +44,7 @@ public enum DataUnit {
*/
TERABYTES("TB", DataSize.ofTerabytes(1));
public static final String[] UNIT_NAMES = new String[]{"B", "kB", "MB", "GB", "TB", "PB", "EB"};
public static final String[] UNIT_NAMES = new String[]{"B", "KB", "MB", "GB", "TB", "PB", "EB"};
private final String suffix;
@ -61,7 +61,7 @@ public enum DataUnit {
}
/**
* 通过后缀返回对应的 {@link DataUnit}
* 通过后缀返回对应的 DataUnit
*
* @param suffix 单位后缀
* @return 匹配到的{@link DataUnit}

View File

@ -0,0 +1,66 @@
package cn.hutool.core.lang.loader;
import cn.hutool.core.lang.Assert;
import java.util.function.Consumer;
import java.util.function.Supplier;
/**
* 函数式懒加载加载器<br>
* 传入用于生成对象的函数在对象需要使用时调用生成对象然后抛弃此生成对象的函数<br>
* 此加载器常用于对象比较庞大而不一定被使用的情况用于减少启动时资源占用问题<br>
* 继承自{@link LazyLoader}如何实现多线程安全由LazyLoader完成
*
* @param <T> 被加载对象类型
* @author Mr.Po
* @see cn.hutool.core.lang.loader.LazyLoader
* @since 5.6.1
*/
public class LazyFunLoader<T> extends LazyLoader<T> {
private static final long serialVersionUID = 1L;
/**
* 用于生成对象的函数
*/
private Supplier<T> supplier;
/**
* 构造
*
* @param supplier 用于生成对象的函数
*/
public LazyFunLoader(Supplier<T> supplier) {
Assert.notNull(supplier);
this.supplier = supplier;
}
@Override
protected T init() {
T t = this.supplier.get();
this.supplier = null;
return t;
}
/**
* 是否已经初始化
*
* @return /
*/
public boolean isInitialize() {
return this.supplier == null;
}
/**
* 如果已经初始化就执行传入函数
*
* @param consumer 待执行函数
*/
public void ifInitialized(Consumer<T> consumer) {
Assert.notNull(consumer);
// 已经初始化
if (this.isInitialize()) {
consumer.accept(this.get());
}
}
}

View File

@ -753,8 +753,8 @@ public class Money implements Serializable, Comparable<Money> {
long total = 0;
for (int i = 0; i < ratios.length; i++) {
total += ratios[i];
for (long element : ratios) {
total += element;
}
long remainder = cent;

View File

@ -719,5 +719,15 @@ public class IdcardUtil {
public Integer getGender() {
return this.gender;
}
@Override
public String toString() {
return "Idcard{" +
"provinceCode='" + provinceCode + '\'' +
", cityCode='" + cityCode + '\'' +
", birthDate=" + birthDate +
", gender=" + gender +
'}';
}
}
}

View File

@ -7,7 +7,7 @@ import java.lang.reflect.Modifier;
/**
* 修饰符工具类
*
*
* @author looly
* @since 4.0.5
*/
@ -15,7 +15,7 @@ public class ModifierUtil {
/**
* 修饰符枚举
*
*
* @author looly
* @since 4.0.5
*/
@ -66,7 +66,7 @@ public class ModifierUtil {
/**
* 是否同时存在一个或多个修饰符可能有多个修饰符如果有指定的修饰符则返回true
*
*
* @param clazz
* @param modifierTypes 修饰符枚举
* @return 是否有指定修饰符如果有返回true否则false如果提供参数为null返回false
@ -80,7 +80,7 @@ public class ModifierUtil {
/**
* 是否同时存在一个或多个修饰符可能有多个修饰符如果有指定的修饰符则返回true
*
*
* @param constructor 构造方法
* @param modifierTypes 修饰符枚举
* @return 是否有指定修饰符如果有返回true否则false如果提供参数为null返回false
@ -94,7 +94,7 @@ public class ModifierUtil {
/**
* 是否同时存在一个或多个修饰符可能有多个修饰符如果有指定的修饰符则返回true
*
*
* @param method 方法
* @param modifierTypes 修饰符枚举
* @return 是否有指定修饰符如果有返回true否则false如果提供参数为null返回false
@ -105,10 +105,10 @@ public class ModifierUtil {
}
return 0 != (method.getModifiers() & modifiersToInt(modifierTypes));
}
/**
* 是否同时存在一个或多个修饰符可能有多个修饰符如果有指定的修饰符则返回true
*
*
* @param field 字段
* @param modifierTypes 修饰符枚举
* @return 是否有指定修饰符如果有返回true否则false如果提供参数为null返回false
@ -119,10 +119,10 @@ public class ModifierUtil {
}
return 0 != (field.getModifiers() & modifiersToInt(modifierTypes));
}
/**
* 是否是Public字段
*
*
* @param field 字段
* @return 是否是Public
*/
@ -132,7 +132,7 @@ public class ModifierUtil {
/**
* 是否是Public方法
*
*
* @param method 方法
* @return 是否是Public
*/
@ -142,7 +142,7 @@ public class ModifierUtil {
/**
* 是否是Public类
*
*
* @param clazz
* @return 是否是Public
*/
@ -152,17 +152,17 @@ public class ModifierUtil {
/**
* 是否是Public构造
*
*
* @param constructor 构造
* @return 是否是Public
*/
public static boolean isPublic(Constructor<?> constructor) {
return hasModifier(constructor, ModifierType.PUBLIC);
}
/**
* 是否是static字段
*
*
* @param field 字段
* @return 是否是static
* @since 4.0.8
@ -173,7 +173,7 @@ public class ModifierUtil {
/**
* 是否是static方法
*
*
* @param method 方法
* @return 是否是static
* @since 4.0.8
@ -184,7 +184,7 @@ public class ModifierUtil {
/**
* 是否是static类
*
*
* @param clazz
* @return 是否是static
* @since 4.0.8
@ -192,7 +192,7 @@ public class ModifierUtil {
public static boolean isStatic(Class<?> clazz) {
return hasModifier(clazz, ModifierType.STATIC);
}
//-------------------------------------------------------------------------------------------------------- Private method start
/**
* 多个修饰符做操作表示同时存在多个修饰符
@ -202,7 +202,7 @@ public class ModifierUtil {
private static int modifiersToInt(ModifierType... modifierTypes) {
int modifier = modifierTypes[0].getValue();
for(int i = 1; i < modifierTypes.length; i++) {
modifier &= modifierTypes[i].getValue();
modifier |= modifierTypes[i].getValue();
}
return modifier;
}

View File

@ -9,6 +9,7 @@ public class ChineseDateTest {
@Test
public void chineseDateTest() {
ChineseDate date = new ChineseDate(DateUtil.parseDate("2020-01-25"));
Assert.assertEquals("2020-01-25 00:00:00", date.getGregorianDate().toString());
Assert.assertEquals(2020, date.getChineseYear());
Assert.assertEquals(1, date.getMonth());
@ -50,6 +51,7 @@ public class ChineseDateTest {
@Test
public void getChineseMonthTest(){
ChineseDate chineseDate = new ChineseDate(2020,6,15);
Assert.assertEquals("2020-08-04 00:00:00", chineseDate.getGregorianDate().toString());
Assert.assertEquals("六月", chineseDate.getChineseMonth());
chineseDate = new ChineseDate(2020,4,15);

View File

@ -550,6 +550,13 @@ public class DateUtilTest {
assert dt != null;
dateStr = dt.toString(simpleDateFormat);
Assert.assertEquals("2018-09-13 13:34:39.999", dateStr);
// 使用UTC时区
dateStr1 = "2018-09-13T13:34:39.99";
dt = DateUtil.parse(dateStr1);
assert dt != null;
dateStr = dt.toString();
Assert.assertEquals("2018-09-13 13:34:39", dateStr);
}
@Test

View File

@ -6,10 +6,6 @@ import org.junit.Ignore;
import org.junit.Test;
import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 文件类型判断单元测试

View File

@ -0,0 +1,45 @@
package cn.hutool.core.lang.loader;
import org.junit.Assert;
import org.junit.Test;
public class LazyFunLoaderTest {
static class BigObject {
private boolean isDestroy = false;
public void destroy() {
this.isDestroy = true;
}
}
@Test
public void test1() {
LazyFunLoader<BigObject> loader = new LazyFunLoader<>(BigObject::new);
Assert.assertNotNull(loader.get());
Assert.assertTrue(loader.isInitialize());
// 对于某些对象在程序关闭时需要进行销毁操作
loader.ifInitialized(BigObject::destroy);
Assert.assertTrue(loader.get().isDestroy);
}
@Test
public void test2() {
LazyFunLoader<BigObject> loader = new LazyFunLoader<>(BigObject::new);
// 若从未使用则可以避免不必要的初始化
loader.ifInitialized(it -> {
Assert.fail();
it.destroy();
});
Assert.assertFalse(loader.isInitialize());
}
}

View File

@ -0,0 +1,21 @@
package cn.hutool.core.util;
import org.junit.Assert;
import org.junit.Test;
import java.lang.reflect.Method;
public class ModifierUtilTest {
@Test
public void hasModifierTest() throws NoSuchMethodException {
Method method = ModifierUtilTest.class.getDeclaredMethod("ddd");
Assert.assertTrue(ModifierUtil.hasModifier(method, ModifierUtil.ModifierType.PRIVATE));
Assert.assertTrue(ModifierUtil.hasModifier(method,
ModifierUtil.ModifierType.PRIVATE,
ModifierUtil.ModifierType.STATIC)
);
}
private static void ddd() {
}
}

View File

@ -7,7 +7,7 @@
<parent>
<groupId>cn.hutool</groupId>
<artifactId>hutool-parent</artifactId>
<version>5.6.1-SNAPSHOT</version>
<version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>hutool-cron</artifactId>

View File

@ -9,7 +9,7 @@
<parent>
<groupId>cn.hutool</groupId>
<artifactId>hutool-parent</artifactId>
<version>5.6.1-SNAPSHOT</version>
<version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>hutool-crypto</artifactId>

View File

@ -9,7 +9,7 @@
<parent>
<groupId>cn.hutool</groupId>
<artifactId>hutool-parent</artifactId>
<version>5.6.1-SNAPSHOT</version>
<version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>hutool-db</artifactId>

View File

@ -52,6 +52,10 @@ public class DialectFactory {
public static final String DRIVER_DM7 = "dm.jdbc.driver.DmDriver";
/** JDBC 驱动 人大金仓 */
public static final String DRIVER_KINGBASE8 = "com.kingbase8.Driver";
/** JDBC 驱动 Ignite thin */
public static final String DRIVER_IGNITE_THIN = "org.apache.ignite.IgniteJdbcThinDriver";
/** JDBC 驱动 ClickHouse */
public static final String DRIVER_CLICK_HOUSE = "ru.yandex.clickhouse.ClickHouseDriver";
private static final Map<DataSource, Dialect> DIALECT_POOL = new ConcurrentHashMap<>();
@ -138,6 +142,12 @@ public class DialectFactory {
} else if (nameContainsProductInfo.contains("kingbase8")) {
// 人大金仓8
driver = DRIVER_KINGBASE8;
} else if (nameContainsProductInfo.contains("ignite")) {
// Ignite thin
driver = DRIVER_IGNITE_THIN;
} else if (nameContainsProductInfo.contains("clickhouse")) {
// ClickHouse
driver = DRIVER_CLICK_HOUSE;
}
return driver;

View File

@ -7,7 +7,7 @@
<parent>
<groupId>cn.hutool</groupId>
<artifactId>hutool-parent</artifactId>
<version>5.6.1-SNAPSHOT</version>
<version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>hutool-dfa</artifactId>

View File

@ -9,7 +9,7 @@
<parent>
<groupId>cn.hutool</groupId>
<artifactId>hutool-parent</artifactId>
<version>5.6.1-SNAPSHOT</version>
<version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>hutool-extra</artifactId>

View File

@ -39,6 +39,12 @@ public class PinyinUtilTest {
Assert.assertEquals("h, s, d, y, g", result);
}
@Test
public void getFirstLetterTest2(){
final String result = PinyinUtil.getFirstLetter("崞阳", ", ");
Assert.assertEquals("g, y", result);
}
@Test
public void getFirstLetterByPinyin4jTest(){
final Pinyin4jEngine engine = new Pinyin4jEngine();

View File

@ -9,7 +9,7 @@
<parent>
<groupId>cn.hutool</groupId>
<artifactId>hutool-parent</artifactId>
<version>5.6.1-SNAPSHOT</version>
<version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>hutool-http</artifactId>

View File

@ -8,7 +8,7 @@ import java.util.regex.Pattern;
/**
* 浏览器对象
*
*
* @author looly
* @since 4.2.1
*/
@ -50,6 +50,8 @@ public class Browser extends UserAgentInfo {
new Browser("wxwork", "wxwork", "wxwork\\/([\\d\\w\\.\\-]+)"),
// 微信
new Browser("MicroMessenger", "MicroMessenger", "MicroMessenger\\/([\\d\\w\\.\\-]+)"),
// 微信小程序
new Browser("miniProgram", "miniProgram", "miniProgram\\/([\\d\\w\\.\\-]+)"),
// 钉钉
new Browser("DingTalk", "DingTalk", "AliApp\\(DingTalk\\/([\\d\\w\\.\\-]+)\\)")
);
@ -59,7 +61,7 @@ public class Browser extends UserAgentInfo {
/**
* 构造
*
*
* @param name 浏览器名称
* @param regex 关键字或表达式
* @param versionRegex 匹配版本的正则
@ -76,7 +78,7 @@ public class Browser extends UserAgentInfo {
/**
* 获取浏览器版本
*
*
* @param userAgentString User-Agent字符串
* @return 版本
*/
@ -86,7 +88,7 @@ public class Browser extends UserAgentInfo {
/**
* 是否移动浏览器
*
*
* @return 是否移动浏览器
*/
public boolean isMobile() {

View File

@ -9,7 +9,7 @@
<parent>
<groupId>cn.hutool</groupId>
<artifactId>hutool-parent</artifactId>
<version>5.6.1-SNAPSHOT</version>
<version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>hutool-json</artifactId>

View File

@ -543,7 +543,7 @@ public class JSONUtil {
* @see JSON#getByPath(String)
*/
public static Object getByPath(JSON json, String expression) {
return (null == json || StrUtil.isBlank(expression)) ? null : json.getByPath(expression);
return getByPath(json, expression, null);
}
/**
@ -572,7 +572,15 @@ public class JSONUtil {
*/
@SuppressWarnings("unchecked")
public static <T> T getByPath(JSON json, String expression, T defaultValue) {
return (T) ObjectUtil.defaultIfNull(getByPath(json, expression), defaultValue);
if((null == json || StrUtil.isBlank(expression))){
return defaultValue;
}
if(null != defaultValue){
final Class<T> type = (Class<T>) defaultValue.getClass();
return ObjectUtil.defaultIfNull(json.getByPath(expression, type), defaultValue);
}
return (T) json.getByPath(expression);
}
/**

View File

@ -0,0 +1,27 @@
package cn.hutool.json;
import cn.hutool.core.bean.BeanUtil;
import lombok.Data;
import org.junit.Assert;
import org.junit.Test;
import java.time.LocalDateTime;
/**
* 测试带毫秒的日期转换
*/
public class IssueI3BS4S {
@Test
public void toBeanTest(){
String jsonStr = "{date: '2021-03-17T06:31:33.99'}";
final Bean1 bean1 = new Bean1();
BeanUtil.copyProperties(JSONUtil.parseObj(jsonStr), bean1);
Assert.assertEquals("2021-03-17T06:31:33.099", bean1.getDate().toString());
}
@Data
public static class Bean1{
private LocalDateTime date;
}
}

View File

@ -5,7 +5,7 @@ import org.junit.Test;
/**
* JSON路径单元测试
*
*
* @author looly
*
*/
@ -19,4 +19,12 @@ public class JSONPathTest {
value = JSONUtil.parseArray(json).getByPath("[1].name");
Assert.assertEquals("mingzi", value);
}
@Test
public void getByPathTest2(){
String str = "{'accountId':111}";
JSON json = JSONUtil.parse(str);
Long accountId = JSONUtil.getByPath(json, "$.accountId", 0L);
Assert.assertEquals(111L, accountId.longValue());
}
}

View File

@ -9,7 +9,7 @@
<parent>
<groupId>cn.hutool</groupId>
<artifactId>hutool-parent</artifactId>
<version>5.6.1-SNAPSHOT</version>
<version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>hutool-log</artifactId>

Some files were not shown because too many files have changed in this diff Show More