mirror of
https://gitee.com/dromara/hutool.git
synced 2025-07-15 23:13:33 +08:00
add method for time
This commit is contained in:
parent
b737c97947
commit
6e9879c821
@ -7,6 +7,9 @@
|
|||||||
|
|
||||||
### 新特性
|
### 新特性
|
||||||
* 【core】 增加MapUtil.removeAny(issue#612@Github)
|
* 【core】 增加MapUtil.removeAny(issue#612@Github)
|
||||||
|
* 【core】 Convert.toList支持[1,2]字符串(issue#I149XN@Gitee)
|
||||||
|
* 【core】 修正DateUtil.thisWeekOfMonth注释错误(issue#614@Github)
|
||||||
|
* 【core】 DateUtil增加toLocalDate等方法,DateTime更好的支持时区
|
||||||
|
|
||||||
### Bug修复
|
### Bug修复
|
||||||
* 【db】 修复MetaUtil.getTableMeta()方法未释放ResultSet的bug(issue#I148GH@Gitee)
|
* 【db】 修复MetaUtil.getTableMeta()方法未释放ResultSet的bug(issue#I148GH@Gitee)
|
||||||
|
@ -1744,6 +1744,7 @@ public class CollUtil {
|
|||||||
/**
|
/**
|
||||||
* 将指定对象全部加入到集合中<br>
|
* 将指定对象全部加入到集合中<br>
|
||||||
* 提供的对象如果为集合类型,会自动转换为目标元素类型<br>
|
* 提供的对象如果为集合类型,会自动转换为目标元素类型<br>
|
||||||
|
* 如果为String,支持类似于[1,2,3,4] 或者 1,2,3,4 这种格式
|
||||||
*
|
*
|
||||||
* @param <T> 元素类型
|
* @param <T> 元素类型
|
||||||
* @param collection 被加入的集合
|
* @param collection 被加入的集合
|
||||||
@ -1772,7 +1773,8 @@ public class CollUtil {
|
|||||||
iter = new ArrayIter<>(value);
|
iter = new ArrayIter<>(value);
|
||||||
} else if (value instanceof CharSequence) {
|
} else if (value instanceof CharSequence) {
|
||||||
// String按照逗号分隔的列表对待
|
// String按照逗号分隔的列表对待
|
||||||
iter = StrUtil.splitTrim((CharSequence) value, CharUtil.COMMA).iterator();
|
final String ArrayStr = StrUtil.unWrap((CharSequence) value, '[', ']');
|
||||||
|
iter = StrUtil.splitTrim(ArrayStr, CharUtil.COMMA).iterator();
|
||||||
} else {
|
} else {
|
||||||
// 其它类型按照单一元素处理
|
// 其它类型按照单一元素处理
|
||||||
iter = CollUtil.newArrayList(value).iterator();
|
iter = CollUtil.newArrayList(value).iterator();
|
||||||
@ -2415,7 +2417,7 @@ public class CollUtil {
|
|||||||
/**
|
/**
|
||||||
* 设置或增加元素。当index小于List的长度时,替换指定位置的值,否则在尾部追加
|
* 设置或增加元素。当index小于List的长度时,替换指定位置的值,否则在尾部追加
|
||||||
*
|
*
|
||||||
* @param <T> 元素类型
|
* @param <T> 元素类型
|
||||||
* @param list List列表
|
* @param list List列表
|
||||||
* @param index 位置
|
* @param index 位置
|
||||||
* @param element 新元素
|
* @param element 新元素
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package cn.hutool.core.convert.impl;
|
package cn.hutool.core.convert.impl;
|
||||||
|
|
||||||
import cn.hutool.core.convert.AbstractConverter;
|
import cn.hutool.core.convert.AbstractConverter;
|
||||||
|
import cn.hutool.core.date.DateTime;
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
@ -87,9 +89,11 @@ public class TemporalAccessorConverter extends AbstractConverter<TemporalAccesso
|
|||||||
} else if (value instanceof TemporalAccessor) {
|
} else if (value instanceof TemporalAccessor) {
|
||||||
return parseFromTemporalAccessor((TemporalAccessor) value);
|
return parseFromTemporalAccessor((TemporalAccessor) value);
|
||||||
} else if (value instanceof Date) {
|
} else if (value instanceof Date) {
|
||||||
return parseFromInstant(((Date) value).toInstant());
|
final DateTime dateTime = DateUtil.date((Date) value);
|
||||||
|
return parseFromInstant(dateTime.toInstant(), dateTime.getZoneId());
|
||||||
}else if (value instanceof Calendar) {
|
}else if (value instanceof Calendar) {
|
||||||
return parseFromInstant(((Calendar) value).toInstant());
|
final Calendar calendar = (Calendar) value;
|
||||||
|
return parseFromInstant(calendar.toInstant(), calendar.getTimeZone().toZoneId());
|
||||||
} else {
|
} else {
|
||||||
return parseFromCharSequence(convertToStr(value));
|
return parseFromCharSequence(convertToStr(value));
|
||||||
}
|
}
|
||||||
@ -103,13 +107,17 @@ public class TemporalAccessorConverter extends AbstractConverter<TemporalAccesso
|
|||||||
*/
|
*/
|
||||||
private TemporalAccessor parseFromCharSequence(CharSequence value) {
|
private TemporalAccessor parseFromCharSequence(CharSequence value) {
|
||||||
final Instant instant;
|
final Instant instant;
|
||||||
|
ZoneId zoneId;
|
||||||
if (null != this.format) {
|
if (null != this.format) {
|
||||||
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(this.format);
|
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(this.format);
|
||||||
instant = formatter.parse(value, Instant::from);
|
instant = formatter.parse(value, Instant::from);
|
||||||
|
zoneId = formatter.getZone();
|
||||||
} else {
|
} else {
|
||||||
instant = DateUtil.parse(value).toInstant();
|
final DateTime dateTime = DateUtil.parse(value);
|
||||||
|
instant = dateTime.toInstant();
|
||||||
|
zoneId = dateTime.getZoneId();
|
||||||
}
|
}
|
||||||
return parseFromInstant(instant);
|
return parseFromInstant(instant, zoneId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -119,7 +127,7 @@ public class TemporalAccessorConverter extends AbstractConverter<TemporalAccesso
|
|||||||
* @return java.time中的对象
|
* @return java.time中的对象
|
||||||
*/
|
*/
|
||||||
private TemporalAccessor parseFromLong(Long time) {
|
private TemporalAccessor parseFromLong(Long time) {
|
||||||
return parseFromInstant(Instant.ofEpochMilli(time));
|
return parseFromInstant(Instant.ofEpochMilli(time), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -137,7 +145,7 @@ public class TemporalAccessorConverter extends AbstractConverter<TemporalAccesso
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(null == result){
|
if(null == result){
|
||||||
result = parseFromInstant(DateUtil.toInstant(temporalAccessor));
|
result = parseFromInstant(DateUtil.toInstant(temporalAccessor), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -205,24 +213,30 @@ public class TemporalAccessorConverter extends AbstractConverter<TemporalAccesso
|
|||||||
* 将TemporalAccessor型时间戳转换为java.time中的对象
|
* 将TemporalAccessor型时间戳转换为java.time中的对象
|
||||||
*
|
*
|
||||||
* @param instant {@link Instant}对象
|
* @param instant {@link Instant}对象
|
||||||
|
* @param zoneId 时区ID,null表示当前系统默认的时区
|
||||||
* @return java.time中的对象
|
* @return java.time中的对象
|
||||||
*/
|
*/
|
||||||
private TemporalAccessor parseFromInstant(Instant instant) {
|
private TemporalAccessor parseFromInstant(Instant instant, ZoneId zoneId) {
|
||||||
if(Instant.class.equals(this.targetType)){
|
if(Instant.class.equals(this.targetType)){
|
||||||
return instant;
|
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;
|
|
||||||
|
zoneId = ObjectUtil.defaultIfNull(zoneId, ZoneId.systemDefault());
|
||||||
|
|
||||||
|
TemporalAccessor result = null;
|
||||||
|
if (LocalDateTime.class.equals(this.targetType)) {
|
||||||
|
result = LocalDateTime.ofInstant(instant, zoneId);
|
||||||
|
} else if (LocalDate.class.equals(this.targetType)) {
|
||||||
|
result = instant.atZone(zoneId).toLocalDate();
|
||||||
|
} else if (LocalTime.class.equals(this.targetType)) {
|
||||||
|
result = instant.atZone(zoneId).toLocalTime();
|
||||||
|
} else if (ZonedDateTime.class.equals(this.targetType)) {
|
||||||
|
result = instant.atZone(zoneId);
|
||||||
|
} else if (OffsetDateTime.class.equals(this.targetType)) {
|
||||||
|
result = OffsetDateTime.ofInstant(instant, zoneId);
|
||||||
|
} else if (OffsetTime.class.equals(this.targetType)) {
|
||||||
|
result = OffsetTime.ofInstant(instant, zoneId);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,8 @@ import java.sql.Timestamp;
|
|||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.temporal.TemporalAccessor;
|
import java.time.temporal.TemporalAccessor;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
@ -156,6 +158,17 @@ public class DateTime extends Date {
|
|||||||
this(instant.toEpochMilli());
|
this(instant.toEpochMilli());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 给定日期Instant的构造
|
||||||
|
*
|
||||||
|
* @param instant {@link Instant} 对象
|
||||||
|
* @param zoneId 时区ID
|
||||||
|
* @since 5.0.5
|
||||||
|
*/
|
||||||
|
public DateTime(Instant instant, ZoneId zoneId) {
|
||||||
|
this(instant.toEpochMilli(), TimeZone.getTimeZone(ObjectUtil.defaultIfNull(zoneId, ZoneId.systemDefault())));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 给定日期TemporalAccessor的构造
|
* 给定日期TemporalAccessor的构造
|
||||||
*
|
*
|
||||||
@ -166,6 +179,16 @@ public class DateTime extends Date {
|
|||||||
this(DateUtil.toInstant(temporalAccessor));
|
this(DateUtil.toInstant(temporalAccessor));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 给定日期ZonedDateTime的构造
|
||||||
|
*
|
||||||
|
* @param zonedDateTime {@link ZonedDateTime} 对象
|
||||||
|
* @since 5.0.5
|
||||||
|
*/
|
||||||
|
public DateTime(ZonedDateTime zonedDateTime) {
|
||||||
|
this(zonedDateTime.toInstant(), zonedDateTime.getZone());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 给定日期毫秒数的构造
|
* 给定日期毫秒数的构造
|
||||||
*
|
*
|
||||||
@ -185,9 +208,7 @@ public class DateTime extends Date {
|
|||||||
*/
|
*/
|
||||||
public DateTime(long timeMillis, TimeZone timeZone) {
|
public DateTime(long timeMillis, TimeZone timeZone) {
|
||||||
super(timeMillis);
|
super(timeMillis);
|
||||||
if (null != timeZone) {
|
this.timeZone = ObjectUtil.defaultIfNull(timeZone, TimeZone.getDefault());
|
||||||
this.timeZone = timeZone;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -215,12 +236,12 @@ public class DateTime extends Date {
|
|||||||
/**
|
/**
|
||||||
* 构建DateTime对象
|
* 构建DateTime对象
|
||||||
*
|
*
|
||||||
* @param dateStr Date字符串
|
* @param dateStr Date字符串
|
||||||
* @param formatter 格式化器,{@link DateTimeFormatter}
|
* @param formatter 格式化器,{@link DateTimeFormatter}
|
||||||
* @since 5.0.0
|
* @since 5.0.0
|
||||||
*/
|
*/
|
||||||
public DateTime(CharSequence dateStr, DateTimeFormatter formatter) {
|
public DateTime(CharSequence dateStr, DateTimeFormatter formatter) {
|
||||||
this(Instant.from(formatter.parse(dateStr)));
|
this(Instant.from(formatter.parse(dateStr)), formatter.getZone());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -770,6 +791,26 @@ public class DateTime extends Date {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取时区
|
||||||
|
*
|
||||||
|
* @return 时区
|
||||||
|
* @since 5.0.5
|
||||||
|
*/
|
||||||
|
public TimeZone getTimeZone(){
|
||||||
|
return this.timeZone;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取时区ID
|
||||||
|
*
|
||||||
|
* @return 时区ID
|
||||||
|
* @since 5.0.5
|
||||||
|
*/
|
||||||
|
public ZoneId getZoneId(){
|
||||||
|
return this.timeZone.toZoneId();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置时区
|
* 设置时区
|
||||||
*
|
*
|
||||||
@ -778,7 +819,7 @@ public class DateTime extends Date {
|
|||||||
* @since 4.1.2
|
* @since 4.1.2
|
||||||
*/
|
*/
|
||||||
public DateTime setTimeZone(TimeZone timeZone) {
|
public DateTime setTimeZone(TimeZone timeZone) {
|
||||||
this.timeZone = timeZone;
|
this.timeZone = ObjectUtil.defaultIfNull(timeZone, TimeZone.getDefault());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,7 +407,7 @@ public class DateUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return 当前日期所在年份的第几周
|
* @return 当前日期所在月份的第几周
|
||||||
*/
|
*/
|
||||||
public static int thisWeekOfMonth() {
|
public static int thisWeekOfMonth() {
|
||||||
return weekOfMonth(date());
|
return weekOfMonth(date());
|
||||||
@ -1966,6 +1966,17 @@ public class DateUtil {
|
|||||||
return null == date ? null : date.toInstant();
|
return null == date ? null : date.toInstant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calendar{@link Instant}对象
|
||||||
|
*
|
||||||
|
* @param calendar Date对象
|
||||||
|
* @return {@link Instant}对象
|
||||||
|
* @since 5.0.5
|
||||||
|
*/
|
||||||
|
public static Instant toInstant(Calendar calendar) {
|
||||||
|
return null == calendar ? null : calendar.toInstant();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Date对象转换为{@link Instant}对象
|
* Date对象转换为{@link Instant}对象
|
||||||
*
|
*
|
||||||
@ -2001,8 +2012,42 @@ public class DateUtil {
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------ Private method start
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link Instant} 转换为 {@link LocalDateTime},使用系统默认时区
|
||||||
|
*
|
||||||
|
* @param instant {@link Instant}
|
||||||
|
* @return {@link LocalDateTime}
|
||||||
|
* @since 5.0.5
|
||||||
|
*/
|
||||||
|
public static LocalDateTime toLocalDateTime(Instant instant){
|
||||||
|
return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link Calendar} 转换为 {@link LocalDateTime},使用系统默认时区
|
||||||
|
*
|
||||||
|
* @param calendar {@link Calendar}
|
||||||
|
* @return {@link LocalDateTime}
|
||||||
|
* @since 5.0.5
|
||||||
|
*/
|
||||||
|
public static LocalDateTime toLocalDateTime(Calendar calendar){
|
||||||
|
return LocalDateTime.ofInstant(calendar.toInstant(), calendar.getTimeZone().toZoneId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link Date} 转换为 {@link LocalDateTime},使用系统默认时区
|
||||||
|
*
|
||||||
|
* @param date {@link Calendar}
|
||||||
|
* @return {@link LocalDateTime}
|
||||||
|
* @since 5.0.5
|
||||||
|
*/
|
||||||
|
public static LocalDateTime toLocalDateTime(Date date){
|
||||||
|
final DateTime dateTime = date(date);
|
||||||
|
return LocalDateTime.ofInstant(dateTime.toInstant(), dateTime.getZoneId());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------ Private method start
|
||||||
/**
|
/**
|
||||||
* 获得指定日期年份和季节<br>
|
* 获得指定日期年份和季节<br>
|
||||||
* 格式:[20131]表示2013年第一季度
|
* 格式:[20131]表示2013年第一季度
|
||||||
|
@ -102,12 +102,7 @@ public class ThreadUtil {
|
|||||||
* @return 执行的方法体
|
* @return 执行的方法体
|
||||||
*/
|
*/
|
||||||
public static Runnable excAsync(final Runnable runnable, boolean isDaemon) {
|
public static Runnable excAsync(final Runnable runnable, boolean isDaemon) {
|
||||||
Thread thread = new Thread() {
|
Thread thread = new Thread(runnable);
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
runnable.run();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
thread.setDaemon(isDaemon);
|
thread.setDaemon(isDaemon);
|
||||||
thread.start();
|
thread.start();
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@ import org.junit.Assert;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 类型转换工具单元测试
|
* 类型转换工具单元测试
|
||||||
@ -179,4 +181,29 @@ public class ConvertTest {
|
|||||||
|
|
||||||
Assert.assertEquals(short2, short1);
|
Assert.assertEquals(short2, short1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void toListTest(){
|
||||||
|
List<String> list = Arrays.asList("1","2");
|
||||||
|
String str = Convert.toStr(list);
|
||||||
|
List<String> list2 = Convert.toList(String.class, str);
|
||||||
|
Assert.assertEquals("1", list2.get(0));
|
||||||
|
Assert.assertEquals("2", list2.get(1));
|
||||||
|
|
||||||
|
List<Integer> list3 = Convert.toList(Integer.class, str);
|
||||||
|
Assert.assertEquals(1, list3.get(0).intValue());
|
||||||
|
Assert.assertEquals(2, list3.get(1).intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void toListTest2(){
|
||||||
|
String str = "1,2";
|
||||||
|
List<String> list2 = Convert.toList(String.class, str);
|
||||||
|
Assert.assertEquals("1", list2.get(0));
|
||||||
|
Assert.assertEquals("2", list2.get(1));
|
||||||
|
|
||||||
|
List<Integer> list3 = Convert.toList(Integer.class, str);
|
||||||
|
Assert.assertEquals(1, list3.get(0).intValue());
|
||||||
|
Assert.assertEquals(2, list3.get(1).intValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user